фронт поправлен

This commit is contained in:
gorbenko.pavel
2026-07-31 12:51:48 +05:00
parent fdd3787e43
commit 06b52c5186
25 changed files with 573 additions and 45 deletions
@@ -1,9 +1,9 @@
namespace Tnsu.ApprovalRoute.Application.RequestTypes;
public sealed record RequestTypeDto(int Id, string Name, string PageUrl, string? ListName, string Section);
public sealed record RequestTypeDto(int Id, string Name, string PageUrl, string? ListName, string? SiteUrl, string Section);
public sealed record CreateRequestTypeRequest(string Name, string PageUrl, string? ListName, string Section);
public sealed record CreateRequestTypeRequest(string Name, string PageUrl, string? ListName, string? SiteUrl, string Section);
public sealed record UpdateRequestTypeRequest(string Name, string PageUrl, string? ListName, string Section);
public sealed record UpdateRequestTypeRequest(string Name, string PageUrl, string? ListName, string? SiteUrl, string Section);
public sealed record PatchRequestTypeRequest(string? Name, string? PageUrl, string? ListName, string? Section);
public sealed record PatchRequestTypeRequest(string? Name, string? PageUrl, string? ListName, string? SiteUrl, string? Section);
@@ -12,7 +12,7 @@ public sealed class RequestTypeService(ApprovalRouteDbContext db)
{
var items = await db.RequestTypes.AsNoTracking()
.OrderBy(x => x.Name)
.Select(x => new RequestTypeDto(x.Id, x.Name, x.PageUrl, x.ListName, x.Section))
.Select(x => new RequestTypeDto(x.Id, x.Name, x.PageUrl, x.ListName, x.SiteUrl, x.Section))
.ToListAsync(cancellationToken);
return Result.Ok<IReadOnlyList<RequestTypeDto>>(items);
@@ -29,11 +29,16 @@ public sealed class RequestTypeService(ApprovalRouteDbContext db)
public async Task<Result<RequestTypeDto>> CreateAsync(CreateRequestTypeRequest request, CancellationToken cancellationToken)
{
if (!RequestTypeFields.IsListReferenceValid(request.ListName, request.SiteUrl))
return Result.Fail<RequestTypeDto>(new ValidationError(
"Имя списка и url сайта SharePoint должны быть заполнены оба вместе или не заполнены вовсе."));
var entity = new RequestType
{
Name = request.Name,
PageUrl = request.PageUrl,
ListName = request.ListName,
SiteUrl = request.SiteUrl,
Section = request.Section
};
db.RequestTypes.Add(entity);
@@ -48,9 +53,14 @@ public sealed class RequestTypeService(ApprovalRouteDbContext db)
if (entity is null)
return Result.Fail<RequestTypeDto>(new NotFoundError("Тип заявки", id));
if (!RequestTypeFields.IsListReferenceValid(request.ListName, request.SiteUrl))
return Result.Fail<RequestTypeDto>(new ValidationError(
"Имя списка и url сайта SharePoint должны быть заполнены оба вместе или не заполнены вовсе."));
entity.Name = request.Name;
entity.PageUrl = request.PageUrl;
entity.ListName = request.ListName;
entity.SiteUrl = request.SiteUrl;
entity.Section = request.Section;
await db.SaveChangesAsync(cancellationToken);
@@ -63,9 +73,17 @@ public sealed class RequestTypeService(ApprovalRouteDbContext db)
if (entity is null)
return Result.Fail<RequestTypeDto>(new NotFoundError("Тип заявки", id));
var listName = request.ListName ?? entity.ListName;
var siteUrl = request.SiteUrl ?? entity.SiteUrl;
if (!RequestTypeFields.IsListReferenceValid(listName, siteUrl))
return Result.Fail<RequestTypeDto>(new ValidationError(
"Имя списка и url сайта SharePoint должны быть заполнены оба вместе или не заполнены вовсе."));
entity.Name = request.Name ?? entity.Name;
entity.PageUrl = request.PageUrl ?? entity.PageUrl;
entity.ListName = request.ListName ?? entity.ListName;
entity.ListName = listName;
entity.SiteUrl = siteUrl;
entity.Section = request.Section ?? entity.Section;
await db.SaveChangesAsync(cancellationToken);
@@ -84,5 +102,5 @@ public sealed class RequestTypeService(ApprovalRouteDbContext db)
return Result.Ok();
}
private static RequestTypeDto ToDto(RequestType e) => new(e.Id, e.Name, e.PageUrl, e.ListName, e.Section);
private static RequestTypeDto ToDto(RequestType e) => new(e.Id, e.Name, e.PageUrl, e.ListName, e.SiteUrl, e.Section);
}
@@ -9,6 +9,9 @@ public sealed class CreateRequestTypeRequestValidator : AbstractValidator<Create
RuleFor(x => x.Name).NotEmpty().WithMessage("Имя типа заявки обязательно.");
RuleFor(x => x.PageUrl).NotEmpty().WithMessage("Url страницы обязателен.");
RuleFor(x => x.Section).NotEmpty().WithMessage("Раздел обязателен.");
RuleFor(x => x)
.Must(x => RequestTypeFields.IsListReferenceValid(x.ListName, x.SiteUrl))
.WithMessage("Имя списка и url сайта SharePoint должны быть заполнены оба вместе или не заполнены вовсе.");
}
}
@@ -19,6 +22,9 @@ public sealed class UpdateRequestTypeRequestValidator : AbstractValidator<Update
RuleFor(x => x.Name).NotEmpty().WithMessage("Имя типа заявки обязательно.");
RuleFor(x => x.PageUrl).NotEmpty().WithMessage("Url страницы обязателен.");
RuleFor(x => x.Section).NotEmpty().WithMessage("Раздел обязателен.");
RuleFor(x => x)
.Must(x => RequestTypeFields.IsListReferenceValid(x.ListName, x.SiteUrl))
.WithMessage("Имя списка и url сайта SharePoint должны быть заполнены оба вместе или не заполнены вовсе.");
}
}
@@ -34,3 +40,9 @@ public sealed class PatchRequestTypeRequestValidator : AbstractValidator<PatchRe
RuleFor(x => x.Section).NotEmpty().WithMessage("Раздел не может быть пустым."));
}
}
internal static class RequestTypeFields
{
public static bool IsListReferenceValid(string? listName, string? siteUrl) =>
string.IsNullOrWhiteSpace(listName) == string.IsNullOrWhiteSpace(siteUrl);
}
@@ -6,6 +6,7 @@ public class RequestType
public string Name { get; set; } = string.Empty;
public string PageUrl { get; set; } = string.Empty;
public string? ListName { get; set; }
public string? SiteUrl { get; set; }
public string Section { get; set; } = string.Empty;
public ICollection<TemplateRoute> Routes { get; set; } = new List<TemplateRoute>();
@@ -17,6 +17,7 @@ public class ApprovalRouteDbContext(DbContextOptions<ApprovalRouteDbContext> opt
e.Property(x => x.Name).HasMaxLength(256).IsRequired();
e.Property(x => x.PageUrl).HasMaxLength(512).IsRequired();
e.Property(x => x.ListName).HasMaxLength(256);
e.Property(x => x.SiteUrl).HasMaxLength(512);
e.Property(x => x.Section).HasMaxLength(256).IsRequired();
});
@@ -12,7 +12,7 @@ using Tnsu.ApprovalRoute.Infrastructure.Persistence;
namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
{
[DbContext(typeof(ApprovalRouteDbContext))]
[Migration("20260731062407_AddRequestTypeListNameSectionAndStepConditionFields")]
[Migration("20260731073536_AddRequestTypeListNameSectionAndStepConditionFields")]
partial class AddRequestTypeListNameSectionAndStepConditionFields
{
/// <inheritdoc />
@@ -57,6 +57,11 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
.HasColumnType("character varying(256)")
.HasColumnName("section");
b.Property<string>("SiteUrl")
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasColumnName("site_url");
b.HasKey("Id")
.HasName("pk_request_types");
@@ -45,6 +45,13 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
maxLength: 256,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "site_url",
table: "request_types",
type: "character varying(512)",
maxLength: 512,
nullable: true);
}
/// <inheritdoc />
@@ -69,6 +76,10 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
migrationBuilder.DropColumn(
name: "section",
table: "request_types");
migrationBuilder.DropColumn(
name: "site_url",
table: "request_types");
}
}
}
@@ -54,6 +54,11 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
.HasColumnType("character varying(256)")
.HasColumnName("section");
b.Property<string>("SiteUrl")
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasColumnName("site_url");
b.HasKey("Id")
.HasName("pk_request_types");