Implémentation de la publication d'un billet
This commit is contained in:
13
src/Yavsc.Server/.config/dotnet-tools.json
Normal file
13
src/Yavsc.Server/.config/dotnet-tools.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"dotnet-ef": {
|
||||||
|
"version": "9.0.6",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-ef"
|
||||||
|
],
|
||||||
|
"rollForward": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -28,9 +28,10 @@ namespace Yavsc.Helpers
|
|||||||
{
|
{
|
||||||
if (readerId == null)
|
if (readerId == null)
|
||||||
{
|
{
|
||||||
var userPosts = dbContext.BlogSpot.Include(
|
var userPosts = dbContext.blogspotPublications.Include(
|
||||||
b => b.Author
|
b => b.BlogPost
|
||||||
).Where(x => ((x.AuthorId == posterId))).ToArray();
|
).Where(x => x.BlogPost.AuthorId == posterId)
|
||||||
|
.Select(x=>x.BlogPost).ToArray();
|
||||||
return userPosts;
|
return userPosts;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
3515
src/Yavsc.Server/Migrations/20250628150549_blogPostPub.Designer.cs
generated
Normal file
3515
src/Yavsc.Server/Migrations/20250628150549_blogPostPub.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
38
src/Yavsc.Server/Migrations/20250628150549_blogPostPub.cs
Normal file
38
src/Yavsc.Server/Migrations/20250628150549_blogPostPub.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Yavsc.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class blogPostPub : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "blogspotPublications",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
BlogpostId = table.Column<long>(type: "bigint", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_blogspotPublications", x => x.BlogpostId);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_blogspotPublications_BlogSpot_BlogpostId",
|
||||||
|
column: x => x.BlogpostId,
|
||||||
|
principalTable: "BlogSpot",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "blogspotPublications");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -857,6 +857,16 @@ namespace Yavsc.Migrations
|
|||||||
b.ToTable("Comment");
|
b.ToTable("Comment");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Yavsc.Models.BlogspotPublication", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("BlogpostId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("BlogpostId");
|
||||||
|
|
||||||
|
b.ToTable("blogspotPublications");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b =>
|
modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("OwnerId")
|
b.Property<string>("OwnerId")
|
||||||
@ -2763,6 +2773,17 @@ namespace Yavsc.Migrations
|
|||||||
b.Navigation("Post");
|
b.Navigation("Post");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Yavsc.Models.BlogspotPublication", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Yavsc.Models.Blog.BlogPost", "BlogPost")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BlogpostId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("BlogPost");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b =>
|
modelBuilder.Entity("Yavsc.Models.Calendar.Schedule", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Yavsc.Models.ApplicationUser", "Owner")
|
b.HasOne("Yavsc.Models.ApplicationUser", "Owner")
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
using Yavsc.Models.Haircut;
|
using Yavsc.Models.Haircut;
|
||||||
using Yavsc.Models.IT.Evolution;
|
using Yavsc.Models.IT.Evolution;
|
||||||
using Yavsc.Models.IT.Fixing;
|
using Yavsc.Models.IT.Fixing;
|
||||||
@ -10,7 +6,6 @@ using Yavsc.Server.Models.EMailing;
|
|||||||
using Yavsc.Server.Models.IT.SourceCode;
|
using Yavsc.Server.Models.IT.SourceCode;
|
||||||
using Yavsc.Server.Models.IT;
|
using Yavsc.Server.Models.IT;
|
||||||
using Yavsc.Models.Streaming;
|
using Yavsc.Models.Streaming;
|
||||||
using Yavsc.Models.Musical;
|
|
||||||
|
|
||||||
namespace Yavsc.Models
|
namespace Yavsc.Models
|
||||||
{
|
{
|
||||||
@ -32,7 +27,6 @@ namespace Yavsc.Models
|
|||||||
using Attributes;
|
using Attributes;
|
||||||
using Bank;
|
using Bank;
|
||||||
using Payment;
|
using Payment;
|
||||||
using Calendar;
|
|
||||||
using Blog;
|
using Blog;
|
||||||
using Yavsc.Abstract.Identity;
|
using Yavsc.Abstract.Identity;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -41,6 +35,7 @@ namespace Yavsc.Models
|
|||||||
|
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
using Yavsc.Abstract.Models.Messaging;
|
using Yavsc.Abstract.Models.Messaging;
|
||||||
|
using Org.BouncyCastle.Asn1.Crmf;
|
||||||
|
|
||||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
||||||
{
|
{
|
||||||
@ -51,7 +46,7 @@ namespace Yavsc.Models
|
|||||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
|
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
protected override void OnModelCreating(ModelBuilder builder)
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
{
|
{
|
||||||
base.OnModelCreating(builder);
|
base.OnModelCreating(builder);
|
||||||
@ -61,7 +56,7 @@ namespace Yavsc.Models
|
|||||||
builder.Entity<Contact>().HasKey(x => new { x.OwnerId, x.UserId });
|
builder.Entity<Contact>().HasKey(x => new { x.OwnerId, x.UserId });
|
||||||
builder.Entity<DeviceDeclaration>().Property(x => x.DeclarationDate).HasDefaultValueSql("LOCALTIMESTAMP");
|
builder.Entity<DeviceDeclaration>().Property(x => x.DeclarationDate).HasDefaultValueSql("LOCALTIMESTAMP");
|
||||||
builder.Entity<BlogTag>().HasKey(x => new { x.PostId, x.TagId });
|
builder.Entity<BlogTag>().HasKey(x => new { x.PostId, x.TagId });
|
||||||
|
|
||||||
builder.Entity<ApplicationUser>().Property(u => u.FullName).IsRequired(false);
|
builder.Entity<ApplicationUser>().Property(u => u.FullName).IsRequired(false);
|
||||||
builder.Entity<ApplicationUser>().Property(u => u.DedicatedGoogleCalendar).IsRequired(false);
|
builder.Entity<ApplicationUser>().Property(u => u.DedicatedGoogleCalendar).IsRequired(false);
|
||||||
builder.Entity<ApplicationUser>().HasMany<ChatConnection>(c => c.Connections);
|
builder.Entity<ApplicationUser>().HasMany<ChatConnection>(c => c.Connections);
|
||||||
@ -81,7 +76,7 @@ namespace Yavsc.Models
|
|||||||
builder.Entity<Models.Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin });
|
builder.Entity<Models.Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin });
|
||||||
builder.Entity<Notification>().Property(n => n.icon).HasDefaultValue("exclam");
|
builder.Entity<Notification>().Property(n => n.icon).HasDefaultValue("exclam");
|
||||||
builder.Entity<ChatRoomAccess>().HasKey(p => new { room = p.ChannelName, user = p.UserId });
|
builder.Entity<ChatRoomAccess>().HasKey(p => new { room = p.ChannelName, user = p.UserId });
|
||||||
builder.Entity<InstrumentRating>().HasAlternateKey(i => new { Instrument= i.InstrumentId, owner = i.OwnerId });
|
builder.Entity<InstrumentRating>().HasAlternateKey(i => new { Instrument = i.InstrumentId, owner = i.OwnerId });
|
||||||
|
|
||||||
foreach (var et in builder.Model.GetEntityTypes())
|
foreach (var et in builder.Model.GetEntityTypes())
|
||||||
{
|
{
|
||||||
@ -89,23 +84,23 @@ namespace Yavsc.Models
|
|||||||
et.FindProperty("DateCreated").SetAfterSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Ignore);
|
et.FindProperty("DateCreated").SetAfterSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.Entity<Activity>().Property(a=>a.ParentCode).IsRequired(false);
|
builder.Entity<Activity>().Property(a => a.ParentCode).IsRequired(false);
|
||||||
//builder.Entity<BlogPost>().HasOne(p => p.Author).WithMany(a => a.Posts);
|
//builder.Entity<BlogPost>().HasOne(p => p.Author).WithMany(a => a.Posts);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is not a failback procedure.
|
// this is not a failback procedure.
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
var appSetup = (string) AppDomain.CurrentDomain.GetData(Constants.YavscConnectionStringEnvName);
|
var appSetup = (string)AppDomain.CurrentDomain.GetData(Constants.YavscConnectionStringEnvName);
|
||||||
if (!string.IsNullOrWhiteSpace(appSetup))
|
if (!string.IsNullOrWhiteSpace(appSetup))
|
||||||
{
|
{
|
||||||
optionsBuilder.UseNpgsql(appSetup);
|
optionsBuilder.UseNpgsql(appSetup);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var envSetup = Environment.GetEnvironmentVariable(Constants.YavscConnectionStringEnvName);
|
var envSetup = Environment.GetEnvironmentVariable(Constants.YavscConnectionStringEnvName);
|
||||||
if (envSetup!=null)
|
if (envSetup != null)
|
||||||
optionsBuilder.UseNpgsql(envSetup);
|
optionsBuilder.UseNpgsql(envSetup);
|
||||||
else optionsBuilder.UseNpgsql();
|
else optionsBuilder.UseNpgsql();
|
||||||
}
|
}
|
||||||
@ -125,7 +120,7 @@ namespace Yavsc.Models
|
|||||||
/// Users posts
|
/// Users posts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public DbSet<Blog.BlogPost> BlogSpot { get; set; }
|
public DbSet<BlogPost> BlogSpot { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Skills powered by this site
|
/// Skills powered by this site
|
||||||
@ -226,14 +221,14 @@ namespace Yavsc.Models
|
|||||||
((ITrackedEntity)entity.Entity).UserModified = userId;
|
((ITrackedEntity)entity.Entity).UserModified = userId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SaveChanges(string userId)
|
public int SaveChanges(string userId)
|
||||||
{
|
{
|
||||||
AddTimestamps(userId);
|
AddTimestamps(userId);
|
||||||
return base.SaveChanges();
|
return base.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<int> SaveChangesAsync(string userId, CancellationToken ctoken = default(CancellationToken))
|
public async Task<int> SaveChangesAsync(string userId, CancellationToken ctoken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
@ -282,7 +277,7 @@ namespace Yavsc.Models
|
|||||||
public DbSet<Comment> Comment { get; set; }
|
public DbSet<Comment> Comment { get; set; }
|
||||||
|
|
||||||
public DbSet<Announce> Announce { get; set; }
|
public DbSet<Announce> Announce { get; set; }
|
||||||
|
|
||||||
// TODO remove and opt for for memory only storing,
|
// TODO remove and opt for for memory only storing,
|
||||||
// as long as it must be set empty each time the service is restarted,
|
// as long as it must be set empty each time the service is restarted,
|
||||||
// and that chatting should be kept as must as possible independent from db context
|
// and that chatting should be kept as must as possible independent from db context
|
||||||
@ -295,7 +290,7 @@ namespace Yavsc.Models
|
|||||||
public DbSet<GitRepositoryReference> GitRepositoryReference { get; set; }
|
public DbSet<GitRepositoryReference> GitRepositoryReference { get; set; }
|
||||||
|
|
||||||
public DbSet<Project> Project { get; set; }
|
public DbSet<Project> Project { get; set; }
|
||||||
|
|
||||||
[Obsolete("use signaled flows")]
|
[Obsolete("use signaled flows")]
|
||||||
public DbSet<LiveFlow> LiveFlow { get; set; }
|
public DbSet<LiveFlow> LiveFlow { get; set; }
|
||||||
|
|
||||||
@ -304,6 +299,8 @@ namespace Yavsc.Models
|
|||||||
public DbSet<InstrumentRating> InstrumentRating { get; set; }
|
public DbSet<InstrumentRating> InstrumentRating { get; set; }
|
||||||
|
|
||||||
public DbSet<Scope> Scopes { get; set; }
|
public DbSet<Scope> Scopes { get; set; }
|
||||||
|
|
||||||
|
public DbSet<BlogspotPublication> blogspotPublications{ get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
src/Yavsc.Server/Models/Blog/BlogspotPublication.cs
Normal file
15
src/Yavsc.Server/Models/Blog/BlogspotPublication.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Yavsc.Models.Blog;
|
||||||
|
|
||||||
|
namespace Yavsc.Models
|
||||||
|
{
|
||||||
|
public class BlogspotPublication
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public long BlogpostId { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey("BlogpostId")]
|
||||||
|
public virtual BlogPost BlogPost{ get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,14 @@
|
|||||||
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Yavsc.Models;
|
using Yavsc.Models;
|
||||||
using Yavsc.ViewModels.Auth;
|
using Yavsc.ViewModels.Auth;
|
||||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||||
using Yavsc.Models.Blog;
|
using Yavsc.Models.Blog;
|
||||||
using Yavsc.Helpers;
|
using Yavsc.Helpers;
|
||||||
using Microsoft.AspNetCore.Localization;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Diagnostics;
|
|
||||||
using Yavsc.ViewModels.Blog;
|
using Yavsc.ViewModels.Blog;
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
|
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
|
||||||
|
|
||||||
@ -69,12 +61,13 @@ namespace Yavsc.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
posts = _context.BlogSpot
|
posts = _context.blogspotPublications
|
||||||
.Include(b => b.Author)
|
.Include(p=>p.BlogPost)
|
||||||
.Include(p=>p.ACL)
|
.Include(b => b.BlogPost.Author)
|
||||||
.Include(p=>p.Tags)
|
.Include(p=>p.BlogPost.ACL)
|
||||||
.Include(p=>p.Comments)
|
.Include(p=>p.BlogPost.Tags)
|
||||||
.Where(p => p.ACL.Count == 0 ).ToArray();
|
.Include(p=>p.BlogPost.Comments)
|
||||||
|
.Where(p => p.BlogPost.ACL.Count == 0 ).Select(p=>p.BlogPost).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = posts.OrderByDescending( p=> p.DateCreated);
|
var data = posts.OrderByDescending( p=> p.DateCreated);
|
||||||
|
@ -6,9 +6,9 @@ namespace Yavsc.Helpers
|
|||||||
{
|
{
|
||||||
public class AsciidocTagHelper : TagHelper
|
public class AsciidocTagHelper : TagHelper
|
||||||
{
|
{
|
||||||
public override async Task ProcessAsync (TagHelperContext context, TagHelperOutput output)
|
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||||
{
|
{
|
||||||
if (context.AllAttributes.ContainsName ("summary"))
|
if (context.AllAttributes.ContainsName("summary"))
|
||||||
{
|
{
|
||||||
var summaryLength = context.AllAttributes["summary"].Value;
|
var summaryLength = context.AllAttributes["summary"].Value;
|
||||||
}
|
}
|
||||||
@ -16,12 +16,23 @@ namespace Yavsc.Helpers
|
|||||||
var content = await output.GetChildContentAsync();
|
var content = await output.GetChildContentAsync();
|
||||||
string text = content.GetContent();
|
string text = content.GetContent();
|
||||||
if (string.IsNullOrWhiteSpace(text)) return;
|
if (string.IsNullOrWhiteSpace(text)) return;
|
||||||
Document document = Document.Parse(text);
|
try
|
||||||
var html = document.ToHtml(2);
|
{
|
||||||
using var stringWriter = new StringWriter();
|
|
||||||
html.WriteTo(stringWriter, HtmlEncoder.Default);
|
Document document = Document.Parse(text);
|
||||||
var processedHere = stringWriter.ToString();
|
var html = document.ToHtml(2);
|
||||||
output.Content.AppendHtml(processedHere);
|
using var stringWriter = new StringWriter();
|
||||||
|
html.WriteTo(stringWriter, HtmlEncoder.Default);
|
||||||
|
var processedHere = stringWriter.ToString();
|
||||||
|
output.Content.AppendHtml(processedHere);
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
// silently render the text
|
||||||
|
output.Content.AppendHtml("<pre>" + text + "</pre>\n");
|
||||||
|
// and an error
|
||||||
|
output.Content.AppendHtml("<pre class=\"parsingError\">" + ex.Message + "</pre>\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
DESTDIR=/srv/www/yavsc
|
DESTDIR=/srv/www/yavsc
|
||||||
CONFIGURATION=Release
|
CONFIGURATION=Release
|
||||||
USER=www-data
|
USER_AND_GROUP=www-data:www-data
|
||||||
SERVICE_PROD=yavsc
|
SERVICE_PROD=yavsc
|
||||||
DOTNET_FRAMEWORK=net9.0
|
DOTNET_FRAMEWORK=net9.0
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ install_service:
|
|||||||
pushInProd: publish
|
pushInProd: publish
|
||||||
sudo systemctl stop $(SERVICE_PROD)
|
sudo systemctl stop $(SERVICE_PROD)
|
||||||
sudo cp -a bin/$(CONFIGURATION)/$(DOTNET_FRAMEWORK)/publish/* $(DESTDIR)
|
sudo cp -a bin/$(CONFIGURATION)/$(DOTNET_FRAMEWORK)/publish/* $(DESTDIR)
|
||||||
sudo chown -R $(USER) $(DESTDIR)
|
sudo chown -R $(USER_AND_GROUP) $(DESTDIR)
|
||||||
sudo sync
|
sudo sync
|
||||||
sudo systemctl start $(SERVICE_PROD)
|
sudo systemctl start $(SERVICE_PROD)
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
|
||||||
@foreach (var group in Model) {
|
@foreach (var group in Model) {
|
||||||
var title = group.Key ?? "@";
|
var title = group.Key ?? "@";
|
||||||
string secondclass="";
|
string secondclass="";
|
||||||
@ -95,6 +96,6 @@
|
|||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@if(Model.Count()==0){<p>Néant</p>}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user