Skip to content

Commit

Permalink
Expressed realms 169 - Implemented Expression Section Repository (#171)
Browse files Browse the repository at this point in the history
- Created Copy of the expression table repo, and renamed things to say
text section
- Moved logic for page load into sub section stuff 
- Creating an expression section should now be fully in place 
- Edit should now be in place 
- Delete should now be updated 
- Fully implemented getting expression details This includes getting
possible parents
- Create and Edit now handle Parent Id Fixed recursion issues
- Split out the options stuff into separate call It now is compatible
with both create and edit actions
  • Loading branch information
noremacskich authored Oct 16, 2024
1 parent 0ef3e74 commit 4aa1f6b
Show file tree
Hide file tree
Showing 20 changed files with 1,626 additions and 2 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace ExpressedRealms.DB.Migrations
{
/// <inheritdoc />
public partial class MakeExpressionSectionsSoftDeletes : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "PublishStatusId",
table: "Expressions",
type: "integer",
nullable: false,
defaultValue: 1,
oldClrType: typeof(int),
oldType: "integer");

migrationBuilder.AddColumn<DateTimeOffset>(
name: "DeletedAt",
table: "ExpressionSections",
type: "timestamp with time zone",
nullable: true);

migrationBuilder.AddColumn<bool>(
name: "IsDeleted",
table: "ExpressionSections",
type: "boolean",
nullable: false,
defaultValue: false);
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DeletedAt",
table: "ExpressionSections");

migrationBuilder.DropColumn(
name: "IsDeleted",
table: "ExpressionSections");

migrationBuilder.AlterColumn<int>(
name: "PublishStatusId",
table: "Expressions",
type: "integer",
nullable: false,
oldClrType: typeof(int),
oldType: "integer",
oldDefaultValue: 1);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasColumnType("text");

b.Property<int>("PublishStatusId")
.HasColumnType("integer");
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasDefaultValue(1);

b.Property<string>("ShortDescription")
.IsRequired()
Expand Down Expand Up @@ -184,9 +186,15 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.IsRequired()
.HasColumnType("text");

b.Property<DateTimeOffset?>("DeletedAt")
.HasColumnType("timestamp with time zone");

b.Property<int>("ExpressionId")
.HasColumnType("integer");

b.Property<bool>("IsDeleted")
.HasColumnType("boolean");

b.Property<string>("Name")
.IsRequired()
.HasMaxLength(150)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using ExpressedRealms.DB.Characters;
using ExpressedRealms.DB.Interceptors;

namespace ExpressedRealms.DB.Models.Expressions;

public class ExpressionSection
public class ExpressionSection : ISoftDelete
{
public int Id { get; set; }
public int ExpressionId { get; set; }
public int SectionTypeId { get; set; }
public int? ParentId { get; set; }
public string Name { get; set; } = null!;
public string Content { get; set; } = null!;
public bool IsDeleted { get; set; }
public DateTimeOffset? DeletedAt { get; set; }

public virtual Expression Expression { get; set; } = null!;
public virtual ExpressionSection? Parent { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public void Configure(EntityTypeBuilder<ExpressionSection> builder)
builder.HasKey(e => e.Id);
builder.Property(e => e.Id).IsRequired();

builder.HasQueryFilter(x => !x.IsDeleted);

builder.Property(e => e.ExpressionId).IsRequired();

builder.Property(e => e.SectionTypeId).IsRequired();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using ExpressedRealms.Repositories.Expressions.Expressions;
using ExpressedRealms.Repositories.Expressions.Expressions.DTOs;
using ExpressedRealms.Repositories.Expressions.ExpressionTextSections;
using ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;
using Microsoft.Extensions.DependencyInjection;

namespace ExpressedRealms.Repositories.Expressions;
Expand All @@ -13,7 +15,12 @@ this IServiceCollection services
services.AddScoped<CreateExpressionDtoValidator>();
services.AddScoped<EditExpressionDtoValidator>();

services.AddScoped<GetExpressionTestSectionOptionsValidator>();
services.AddScoped<CreateExpressionTextSectionDtoValidator>();
services.AddScoped<EditExpressionTextSectionDtoValidator>();

services.AddScoped<IExpressionRepository, ExpressionRepository>();
services.AddScoped<IExpressionTextSectionRepository, ExpressionTextSectionRepository>();
return services;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ExpressedRealms.Repositories.Expressions.Expressions.DTOs;

public record CreateExpressionTextSectionDto
{
public string Name { get; set; } = null!;
public string Content { get; set; } = null!;
public int ExpressionId { get; set; }
public int SectionTypeId { get; set; }
public int? ParentId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using ExpressedRealms.DB;
using ExpressedRealms.Repositories.Expressions.ExpressionTextSections.Helpers;
using FluentValidation;
using Microsoft.EntityFrameworkCore;

namespace ExpressedRealms.Repositories.Expressions.Expressions.DTOs;

public class CreateExpressionTextSectionDtoValidator
: AbstractValidator<CreateExpressionTextSectionDto>
{
public CreateExpressionTextSectionDtoValidator(ExpressedRealmsDbContext dbContext)
{
RuleFor(x => x.Name).MaximumLength(50).NotEmpty();
RuleFor(x => x.Content).NotEmpty();
RuleFor(x => x.SectionTypeId)
.MustAsync(
async (sectionTypeId, cancellationToken) =>
{
return await dbContext.ExpressionSectionTypes.AnyAsync(
x => x.Id == sectionTypeId,
cancellationToken
);
}
)
.WithMessage("This is not a valid Section Type");
RuleFor(x => x.ExpressionId)
.MustAsync(
async (expressionId, cancellationToken) =>
{
return await dbContext.Expressions.AnyAsync(
x => x.Id == expressionId,
cancellationToken
);
}
)
.WithMessage("This is not a valid Expression Id");
RuleFor(x => x)
.MustAsync(
async (expressionSection, cancellationToken) =>
{
var expressionSections = await dbContext
.ExpressionSections.Where(x =>
x.ExpressionId == expressionSection.ExpressionId
)
.ToListAsync();

var validParentIds = RecursiveFunctions.GetValidParentIds(
expressionSections,
null,
0
);
return validParentIds.Contains(expressionSection.ParentId.Value);
}
)
.When(x => x.ParentId != null)
.WithMessage("This is not a valid Parent Id");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public record EditExpressionTextSectionDto
{
public int Id { get; init; }
public string Name { get; set; } = null!;
public string Content { get; set; } = null!;
public int ExpressionId { get; set; }
public int SectionTypeId { get; set; }
public int? ParentId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using ExpressedRealms.DB;
using ExpressedRealms.Repositories.Expressions.ExpressionTextSections.Helpers;
using FluentValidation;
using Microsoft.EntityFrameworkCore;

namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public class EditExpressionTextSectionDtoValidator : AbstractValidator<EditExpressionTextSectionDto>
{
public EditExpressionTextSectionDtoValidator(ExpressedRealmsDbContext dbContext)
{
RuleFor(x => x.Id).NotEmpty().GreaterThan(0);
RuleFor(x => x.Name).MaximumLength(50).NotEmpty();
RuleFor(x => x.Content).NotEmpty();
RuleFor(x => x.SectionTypeId)
.MustAsync(
async (sectionTypeId, cancellationToken) =>
{
return await dbContext.ExpressionSectionTypes.AnyAsync(
x => x.Id == sectionTypeId,
cancellationToken
);
}
)
.WithMessage("This is not a valid Section Type");
RuleFor(x => x.ExpressionId)
.MustAsync(
async (expressionId, cancellationToken) =>
{
return await dbContext.Expressions.AnyAsync(
x => x.Id == expressionId,
cancellationToken
);
}
)
.WithMessage("This is not a valid Expression Id");
RuleFor(x => x)
.MustAsync(
async (expressionSection, cancellationToken) =>
{
var expressionSections = await dbContext
.ExpressionSections.Where(x =>
x.ExpressionId == expressionSection.ExpressionId
)
.ToListAsync();

var validParentIds = RecursiveFunctions.GetValidParentIds(
expressionSections,
null,
0
);
return validParentIds.Contains(expressionSection.ParentId.Value);
}
)
.When(x => x.ParentId != null)
.WithMessage("This is not a valid Parent Id");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public class ExpressionSectionDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Content { get; set; }
public List<ExpressionSectionDto> SubSections { get; set; } = new();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public record ExpressionTextSectionDto
{
public string Name { get; set; } = null!;
public string ShortDescription { get; set; } = null!;
public string NavMenuImage { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public class ExpressionTextSectionOptions
{
public List<ExpressionSectionDto> AvailableParents { get; set; } = null!;
public List<SectionTypeDto> ExpressionSectionTypes { get; set; } = null!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public class GetExpressionTextSectionDto
{
public int Id { get; init; }
public string Name { get; set; } = null!;
public string Content { get; set; }
public int? ParentId { get; set; }
public int SectionTypeId { get; set; }
public List<SectionTypeDto> SectionTypes { get; set; } = null!;
public List<ExpressionSectionDto> AvailableParents { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public class GetExpressionTestSectionOptionsDto
{
public int ExpressionId { get; set; }
public int? SectionId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using ExpressedRealms.DB;
using FluentValidation;
using Microsoft.EntityFrameworkCore;

namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public class GetExpressionTestSectionOptionsValidator
: AbstractValidator<GetExpressionTestSectionOptionsDto>
{
public GetExpressionTestSectionOptionsValidator(ExpressedRealmsDbContext dbContext)
{
RuleFor(x => x.SectionId)
.MustAsync(
async (sectionId, cancellationToken) =>
{
return await dbContext.ExpressionSections.AnyAsync(
x => x.Id == sectionId,
cancellationToken
);
}
)
.When(x => x.SectionId is not null)
.WithMessage("This is not a valid Section");
RuleFor(x => x.ExpressionId)
.MustAsync(
async (expressionId, cancellationToken) =>
{
return await dbContext.Expressions.AnyAsync(
x => x.Id == expressionId,
cancellationToken
);
}
)
.WithMessage("This is not a valid Expression Id");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ExpressedRealms.Repositories.Expressions.ExpressionTextSections.DTOs;

public class SectionTypeDto
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public string? Description { get; set; }
}
Loading

0 comments on commit 4aa1f6b

Please sign in to comment.