Blazorise #4
@ -17,7 +17,7 @@ namespace UserService.DatabaseLayer.DataModels
|
|||||||
var arizona = new OrganizationUnit{CommonName = "Arizona" , Id = -4, ParentId = -5 };
|
var arizona = new OrganizationUnit{CommonName = "Arizona" , Id = -4, ParentId = -5 };
|
||||||
var france = new OrganizationUnit{CommonName = "France" , Id = -3, ParentId = -2 };
|
var france = new OrganizationUnit{CommonName = "France" , Id = -3, ParentId = -2 };
|
||||||
modelBuilder.Entity<OrganizationUnit>().HasData(users, groups, germany, usa, arizona, france);
|
modelBuilder.Entity<OrganizationUnit>().HasData(users, groups, germany, usa, arizona, france);
|
||||||
var user = new User { CommonName = "holger", IsActive = true, Id = -7, ParentId = germany.Id };
|
var user = new User { CommonName = Environment.UserName, IsActive = true, Id = -7, ParentId = users.Id };
|
||||||
modelBuilder.Entity<User>().HasData(user);
|
modelBuilder.Entity<User>().HasData(user);
|
||||||
var secGroup = new SecurityGroup { CommonName = "Global Admin", Id = -8, ParentId = groups.Id };
|
var secGroup = new SecurityGroup { CommonName = "Global Admin", Id = -8, ParentId = groups.Id };
|
||||||
modelBuilder.Entity<SecurityGroup>().HasData(secGroup);
|
modelBuilder.Entity<SecurityGroup>().HasData(secGroup);
|
||||||
@ -39,7 +39,6 @@ namespace UserService.DatabaseLayer.DataModels
|
|||||||
.HasOne(bc => bc.Member)
|
.HasOne(bc => bc.Member)
|
||||||
.WithMany(c => c!.Members)
|
.WithMany(c => c!.Members)
|
||||||
.HasForeignKey(bc => bc.MemberId);
|
.HasForeignKey(bc => bc.MemberId);
|
||||||
|
|
||||||
modelBuilder.Entity<Node>()
|
modelBuilder.Entity<Node>()
|
||||||
.HasMany(c => c.Children)
|
.HasMany(c => c.Children)
|
||||||
.WithOne(e => e.Parent!)
|
.WithOne(e => e.Parent!)
|
||||||
|
@ -9,16 +9,16 @@ using UserService.DatabaseLayer.DataModels;
|
|||||||
namespace UserService.DatabaseLayer.Migrations
|
namespace UserService.DatabaseLayer.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(UserServiceDbContext))]
|
[DbContext(typeof(UserServiceDbContext))]
|
||||||
[Migration("20200725195658_initial")]
|
[Migration("20200821193933_InitialCreate")]
|
||||||
partial class initial
|
partial class InitialCreate
|
||||||
{
|
{
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "3.1.6");
|
.HasAnnotation("ProductVersion", "3.1.7");
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -47,7 +47,7 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("MemberId")
|
b.Property<int>("MemberId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -69,9 +69,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Member", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.Member", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
|
||||||
|
|
||||||
b.Property<string>("EMail")
|
b.Property<string>("EMail")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -79,9 +79,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
b.HasDiscriminator().HasValue("Member");
|
b.HasDiscriminator().HasValue("Member");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
|
||||||
|
|
||||||
b.Property<int?>("ManagerId")
|
b.Property<int?>("ManagerId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -127,9 +127,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.SecurityGroup", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.SecurityGroup", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
|
||||||
|
|
||||||
b.HasDiscriminator().HasValue("SecurityGroup");
|
b.HasDiscriminator().HasValue("SecurityGroup");
|
||||||
|
|
||||||
@ -142,9 +142,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.User", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.User", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
|
||||||
|
|
||||||
b.Property<string>("FirstName")
|
b.Property<string>("FirstName")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -162,36 +162,36 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
{
|
{
|
||||||
Id = -7,
|
Id = -7,
|
||||||
CommonName = "holger",
|
CommonName = "holger",
|
||||||
ParentId = -6,
|
ParentId = -2,
|
||||||
IsActive = true
|
IsActive = true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.Node", "Parent")
|
b.HasOne("UserService.Infrastructure.DataModels.Node", "Parent")
|
||||||
.WithMany("Children")
|
.WithMany("Children")
|
||||||
.HasForeignKey("ParentId");
|
.HasForeignKey("ParentId");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Member")
|
b.HasOne("UserService.Infrastructure.DataModels.Member", "Member")
|
||||||
.WithMany("Members")
|
.WithMany("Members")
|
||||||
.HasForeignKey("MemberId")
|
.HasForeignKey("MemberId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.User", "User")
|
b.HasOne("UserService.Infrastructure.DataModels.User", "User")
|
||||||
.WithMany("MemberOf")
|
.WithMany("MemberOf")
|
||||||
.HasForeignKey("UserId")
|
.HasForeignKey("UserId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Manager")
|
b.HasOne("UserService.Infrastructure.DataModels.Member", "Manager")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ManagerId");
|
.HasForeignKey("ManagerId");
|
||||||
});
|
});
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace UserService.DatabaseLayer.Migrations
|
namespace UserService.DatabaseLayer.Migrations
|
||||||
{
|
{
|
||||||
public partial class initial : Migration
|
public partial class InitialCreate : Migration
|
||||||
{
|
{
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
@ -90,13 +90,13 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
|
|
||||||
migrationBuilder.InsertData(
|
migrationBuilder.InsertData(
|
||||||
table: "Node",
|
table: "Node",
|
||||||
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail" },
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail", "FirstName", "IsActive", "LastName" },
|
||||||
values: new object[] { -8, "Global Admin", null, "SecurityGroup", -1, null });
|
values: new object[] { -7, "holger", null, "User", -2, null, null, true, null });
|
||||||
|
|
||||||
migrationBuilder.InsertData(
|
migrationBuilder.InsertData(
|
||||||
table: "Node",
|
table: "Node",
|
||||||
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail", "FirstName", "IsActive", "LastName" },
|
columns: new[] { "Id", "CommonName", "Description", "Discriminator", "ParentId", "EMail" },
|
||||||
values: new object[] { -7, "holger", null, "User", -6, null, null, true, null });
|
values: new object[] { -8, "Global Admin", null, "SecurityGroup", -1, null });
|
||||||
|
|
||||||
migrationBuilder.InsertData(
|
migrationBuilder.InsertData(
|
||||||
table: "Node",
|
table: "Node",
|
@ -1,7 +1,8 @@
|
|||||||
// <auto-generated />
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using UserService.DatabaseLayer.DataModels;
|
using UserService.DatabaseLayer.DataModels;
|
||||||
|
|
||||||
namespace UserService.DatabaseLayer.Migrations
|
namespace UserService.DatabaseLayer.Migrations
|
||||||
@ -13,9 +14,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "3.1.6");
|
.HasAnnotation("ProductVersion", "3.1.7");
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
@ -44,7 +45,7 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
b.HasDiscriminator<string>("Discriminator").HasValue("Node");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("MemberId")
|
b.Property<int>("MemberId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -66,9 +67,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Member", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.Member", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
|
||||||
|
|
||||||
b.Property<string>("EMail")
|
b.Property<string>("EMail")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -76,9 +77,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
b.HasDiscriminator().HasValue("Member");
|
b.HasDiscriminator().HasValue("Member");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Node");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Node");
|
||||||
|
|
||||||
b.Property<int?>("ManagerId")
|
b.Property<int?>("ManagerId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
@ -124,9 +125,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.SecurityGroup", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.SecurityGroup", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
|
||||||
|
|
||||||
b.HasDiscriminator().HasValue("SecurityGroup");
|
b.HasDiscriminator().HasValue("SecurityGroup");
|
||||||
|
|
||||||
@ -139,9 +140,9 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.User", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.User", b =>
|
||||||
{
|
{
|
||||||
b.HasBaseType("UserService.DatabaseLayer.DataModels.Member");
|
b.HasBaseType("UserService.Infrastructure.DataModels.Member");
|
||||||
|
|
||||||
b.Property<string>("FirstName")
|
b.Property<string>("FirstName")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
@ -159,36 +160,36 @@ namespace UserService.DatabaseLayer.Migrations
|
|||||||
{
|
{
|
||||||
Id = -7,
|
Id = -7,
|
||||||
CommonName = "holger",
|
CommonName = "holger",
|
||||||
ParentId = -6,
|
ParentId = -2,
|
||||||
IsActive = true
|
IsActive = true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.Node", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.Node", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.Node", "Parent")
|
b.HasOne("UserService.Infrastructure.DataModels.Node", "Parent")
|
||||||
.WithMany("Children")
|
.WithMany("Children")
|
||||||
.HasForeignKey("ParentId");
|
.HasForeignKey("ParentId");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.UserMember", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.UserMember", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Member")
|
b.HasOne("UserService.Infrastructure.DataModels.Member", "Member")
|
||||||
.WithMany("Members")
|
.WithMany("Members")
|
||||||
.HasForeignKey("MemberId")
|
.HasForeignKey("MemberId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.User", "User")
|
b.HasOne("UserService.Infrastructure.DataModels.User", "User")
|
||||||
.WithMany("MemberOf")
|
.WithMany("MemberOf")
|
||||||
.HasForeignKey("UserId")
|
.HasForeignKey("UserId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("UserService.DatabaseLayer.DataModels.OrganizationUnit", b =>
|
modelBuilder.Entity("UserService.Infrastructure.DataModels.OrganizationUnit", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("UserService.DatabaseLayer.DataModels.Member", "Manager")
|
b.HasOne("UserService.Infrastructure.DataModels.Member", "Manager")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ManagerId");
|
.HasForeignKey("ManagerId");
|
||||||
});
|
});
|
||||||
|
@ -5,9 +5,6 @@ namespace UserService.Infrastructure.DataModels
|
|||||||
{
|
{
|
||||||
public abstract class Member : Node
|
public abstract class Member : Node
|
||||||
{
|
{
|
||||||
[EmailAddress]
|
|
||||||
public string? EMail { get; set; }
|
|
||||||
|
|
||||||
public ICollection<UserMember> Members { get; set; } = new List<UserMember>();
|
public ICollection<UserMember> Members { get; set; } = new List<UserMember>();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace UserService.Infrastructure.DataModels
|
namespace UserService.Infrastructure.DataModels
|
||||||
{
|
{
|
||||||
@ -8,6 +10,9 @@ namespace UserService.Infrastructure.DataModels
|
|||||||
public string? LastName { get; set; }
|
public string? LastName { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
|
|
||||||
|
[EmailAddress]
|
||||||
|
public string? EMail { get; set; }
|
||||||
|
|
||||||
public string FullName => $"{FirstName} {LastName}";
|
public string FullName => $"{FirstName} {LastName}";
|
||||||
|
|
||||||
public IEnumerable<UserMember> MemberOf { get; set; } = new List<UserMember>();
|
public IEnumerable<UserMember> MemberOf { get; set; } = new List<UserMember>();
|
||||||
|
23
UserService.Infrastructure/NodeExtensions.cs
Normal file
23
UserService.Infrastructure/NodeExtensions.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UserService.Infrastructure.DataModels;
|
||||||
|
|
||||||
|
namespace UserService.Infrastructure
|
||||||
|
{
|
||||||
|
public static class NodeExtensions
|
||||||
|
{
|
||||||
|
public static void MapFields(this User user, Dictionary<string, object> values)
|
||||||
|
{
|
||||||
|
if (user == null) throw new ArgumentNullException(nameof(user));
|
||||||
|
if (values == null) throw new ArgumentNullException(nameof(values));
|
||||||
|
var properties = user.GetType().GetProperties();
|
||||||
|
foreach (var keyValuePair in values)
|
||||||
|
{
|
||||||
|
var propertyInfo = properties.FirstOrDefault(x => x.Name == keyValuePair.Key);
|
||||||
|
if (propertyInfo == null) continue;
|
||||||
|
propertyInfo.SetValue(user, keyValuePair.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -7,13 +7,13 @@ namespace UserService.Infrastructure
|
|||||||
{
|
{
|
||||||
public static class Validators
|
public static class Validators
|
||||||
{
|
{
|
||||||
public static bool? ValidateEmail(string mailAddress)
|
public static bool? ValidateEmail(string? mailAddress)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(mailAddress)) return null;
|
if (string.IsNullOrEmpty(mailAddress)) return null;
|
||||||
return new EmailAddressAttribute().IsValid(mailAddress);
|
return new EmailAddressAttribute().IsValid(mailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool? ValidateCommonName(string commonName, IReadOnlyList<User> users)
|
public static bool? ValidateCommonName(string? commonName, IEnumerable<Member> users)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(commonName)) return false;
|
if (string.IsNullOrEmpty(commonName)) return false;
|
||||||
return users.All(x => x.CommonName != commonName);
|
return users.All(x => x.CommonName != commonName);
|
||||||
|
BIN
UserService.db
BIN
UserService.db
Binary file not shown.
36
UserService/Pages/MembersBase.cs
Normal file
36
UserService/Pages/MembersBase.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Blazorise;
|
||||||
|
using Blazorise.DataGrid;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using UserService.Infrastructure;
|
||||||
|
using UserService.Infrastructure.DataModels;
|
||||||
|
|
||||||
|
namespace UserService.Pages
|
||||||
|
{
|
||||||
|
public abstract class MembersBase<T> : ComponentBase where T : Member
|
||||||
|
{
|
||||||
|
protected IReadOnlyList<OrganizationUnit>? OrganizationUnits { get; set; }
|
||||||
|
|
||||||
|
protected IReadOnlyList<T>? Members { get; set; }
|
||||||
|
|
||||||
|
protected string? CustomFilterValue { get; set; }
|
||||||
|
|
||||||
|
protected abstract Task RowInsertingCallback(CancellableRowChange<T, Dictionary<string, object>> arg);
|
||||||
|
|
||||||
|
protected abstract Task RowInsertedCallback(SavedRowItem<T, Dictionary<string, object>> arg);
|
||||||
|
protected abstract Task RowDeletingCallback(CancellableRowChange<T> arg);
|
||||||
|
protected abstract Task RowUpdatingCallback(CancellableRowChange<T, Dictionary<string, object>> arg);
|
||||||
|
protected abstract bool OnCustomFilter(T model);
|
||||||
|
|
||||||
|
protected void ValidateCommonName(ValidatorEventArgs e)
|
||||||
|
{
|
||||||
|
if (e == null) throw new ArgumentNullException(nameof(e));
|
||||||
|
var commonName = e.Value?.ToString();
|
||||||
|
var validationResult = Validators.ValidateCommonName(commonName, Members ?? Enumerable.Empty<Member>());
|
||||||
|
e.Status = validationResult == false ? ValidationStatus.Error : ValidationStatus.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<h1>Table of all security groups</h1>
|
<h1>Table of all security groups</h1>
|
||||||
|
|
||||||
@if (Groups is null)
|
@if (Members is null)
|
||||||
{
|
{
|
||||||
<p>
|
<p>
|
||||||
<em>Loading...</em>
|
<em>Loading...</em>
|
||||||
@ -12,10 +12,76 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<DataGrid TItem="SecurityGroup" Data="@Groups">
|
<TextEdit Placeholder="Search" Size="Size.Large" @bind-Text="@CustomFilterValue" />
|
||||||
<DataGridCommandColumn TItem="User" />
|
|
||||||
<DataGridColumn TItem="SecurityGroup" Field="@nameof(SecurityGroup.Id)" Caption="#" Sortable="false" />
|
<DataGrid
|
||||||
<DataGridColumn TItem="SecurityGroup" Field="@nameof(SecurityGroup.CommonName)" Caption="CN" Editable="true" />
|
TItem="SecurityGroup"
|
||||||
<DataGridColumn TItem="SecurityGroup" Field="@nameof(SecurityGroup.EMail)" Caption="EMail" Editable="true" />
|
RowSelectable="@(u => false)"
|
||||||
</DataGrid>
|
CustomFilter="@OnCustomFilter"
|
||||||
|
Sortable="true"
|
||||||
|
Editable="true"
|
||||||
|
EditMode="DataGridEditMode.Inline"
|
||||||
|
RowRemoving="RowDeletingCallback"
|
||||||
|
Data="@Members"
|
||||||
|
RowInserted="RowInsertedCallback"
|
||||||
|
RowInserting="RowInsertingCallback"
|
||||||
|
RowUpdating="RowUpdatingCallback">
|
||||||
|
<DataGridCommandColumn TItem="SecurityGroup">
|
||||||
|
<NewCommandTemplate>
|
||||||
|
<Button Color="Color.Success" Clicked="@context.Clicked" title="Create security group">
|
||||||
|
<i class="fas fa-users"></i>
|
||||||
|
</Button>
|
||||||
|
</NewCommandTemplate>
|
||||||
|
<EditCommandTemplate>
|
||||||
|
<Button Color="Color.Primary" Clicked="@context.Clicked" title="Edit security group">
|
||||||
|
<i class="fa fa-user-edit"></i>
|
||||||
|
</Button>
|
||||||
|
</EditCommandTemplate>
|
||||||
|
<DeleteCommandTemplate>
|
||||||
|
<Button Color="Color.Danger" Clicked="@context.Clicked" title="Delete security group">
|
||||||
|
<i class="fa fa-user-minus"></i>
|
||||||
|
</Button>
|
||||||
|
</DeleteCommandTemplate>
|
||||||
|
<SaveCommandTemplate>
|
||||||
|
<Button Color="Color.Success" Clicked="@context.Clicked" title="Save security group">
|
||||||
|
<i class="fas fa-save"></i>
|
||||||
|
</Button>
|
||||||
|
</SaveCommandTemplate>
|
||||||
|
<CancelCommandTemplate>
|
||||||
|
<Button Color="Color.Danger" Clicked="@context.Clicked" title="Cancel editing">
|
||||||
|
<i class="far fa-times-circle"></i>
|
||||||
|
</Button>
|
||||||
|
</CancelCommandTemplate>
|
||||||
|
</DataGridCommandColumn>
|
||||||
|
<DataGridColumn TItem="SecurityGroup" Field="@nameof(SecurityGroup.Id)" Caption="#" Sortable="false" />
|
||||||
|
|
||||||
|
<DataGridColumn TItem="SecurityGroup" Field="@nameof(SecurityGroup.CommonName)" Caption="CN" CellsEditableOnEditCommand="false" Editable="true">
|
||||||
|
<EditTemplate>
|
||||||
|
<Validation Validator="@ValidateCommonName">
|
||||||
|
<TextEdit Placeholder="Enter common name" Text="@((string)(((CellEditContext)context).CellValue))" TextChanged="@(v=>((CellEditContext)context).CellValue=v)">
|
||||||
|
<Feedback>
|
||||||
|
<ValidationSuccess></ValidationSuccess>
|
||||||
|
<ValidationError>Please enter a valid common name!</ValidationError>
|
||||||
|
</Feedback>
|
||||||
|
</TextEdit>
|
||||||
|
</Validation>
|
||||||
|
</EditTemplate>
|
||||||
|
</DataGridColumn>
|
||||||
|
<DataGridSelectColumn TItem="SecurityGroup" Field="@nameof(SecurityGroup.ParentId)" Caption="Parent" Editable="true">
|
||||||
|
<DisplayTemplate>
|
||||||
|
@{
|
||||||
|
var name = ((SecurityGroup) context ).Parent?.CommonName ?? "-";
|
||||||
|
@name
|
||||||
|
}
|
||||||
|
</DisplayTemplate>
|
||||||
|
<EditTemplate>
|
||||||
|
<Select TValue="int?" SelectedValue="@((int?)(context.CellValue))" SelectedValueChanged="@(v => context.CellValue = v)" >
|
||||||
|
@foreach (var item in OrganizationUnits ?? Enumerable.Empty<OrganizationUnit>())
|
||||||
|
{
|
||||||
|
<SelectItem TValue="int" Value="@(item.Id)">@item.CommonName</SelectItem>
|
||||||
|
}
|
||||||
|
</Select>
|
||||||
|
</EditTemplate>
|
||||||
|
</DataGridSelectColumn>
|
||||||
|
</DataGrid>
|
||||||
}
|
}
|
@ -1,47 +1,49 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Blazorise.DataGrid;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using UserService.DatabaseLayer.Repository;
|
using UserService.DatabaseLayer.Repository;
|
||||||
using UserService.Infrastructure.DataModels;
|
using UserService.Infrastructure.DataModels;
|
||||||
|
|
||||||
namespace UserService.Pages
|
namespace UserService.Pages
|
||||||
{
|
{
|
||||||
public class SecurityGroupsBase : ComponentBase
|
public class SecurityGroupsBase : MembersBase<SecurityGroup>
|
||||||
{
|
{
|
||||||
[Inject] private ISecurityGroupsRepository SecurityGroupsRepository { get; set; } = null!;
|
[Inject] private ISecurityGroupsRepository SecurityGroupsRepository { get; set; } = null!;
|
||||||
[Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!;
|
[Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!;
|
||||||
|
|
||||||
protected bool DialogIsOpen { get; set; }
|
|
||||||
protected SecurityGroup? SecurityGroupToEdit { get; set; }
|
|
||||||
|
|
||||||
protected IReadOnlyList<SecurityGroup>? Groups { get; set; }
|
|
||||||
protected IReadOnlyList<OrganizationUnit>? OrganizationUnits { get; set; }
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
Groups = await SecurityGroupsRepository.GetAllAsync().ConfigureAwait(false);
|
Members = await SecurityGroupsRepository.GetAllAsync().ConfigureAwait(false);
|
||||||
OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false);
|
OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void EditSecurityGroup(SecurityGroup securityGroup)
|
/// <inheritdoc />
|
||||||
|
protected override async Task RowInsertingCallback(CancellableRowChange<SecurityGroup, Dictionary<string, object>> arg)
|
||||||
{
|
{
|
||||||
SecurityGroupToEdit = securityGroup;
|
|
||||||
DialogIsOpen = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task OkClick()
|
/// <inheritdoc />
|
||||||
|
protected override async Task RowInsertedCallback(SavedRowItem<SecurityGroup, Dictionary<string, object>> arg)
|
||||||
{
|
{
|
||||||
if (!(SecurityGroupToEdit is null))
|
|
||||||
{
|
|
||||||
await SecurityGroupsRepository.UpdateAsync(SecurityGroupToEdit).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
DialogIsOpen = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task DeleteSecurityGroup(SecurityGroup securityGroup)
|
/// <inheritdoc />
|
||||||
|
protected override async Task RowDeletingCallback(CancellableRowChange<SecurityGroup> arg)
|
||||||
{
|
{
|
||||||
await SecurityGroupsRepository.DeleteAsync(securityGroup).ConfigureAwait(false);
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override async Task RowUpdatingCallback(CancellableRowChange<SecurityGroup, Dictionary<string, object>> arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override bool OnCustomFilter(SecurityGroup model)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<h1>List of all users</h1>
|
<h1>List of all users</h1>
|
||||||
|
|
||||||
@if (Users == null)
|
@if (Members == null)
|
||||||
{
|
{
|
||||||
<p>
|
<p>
|
||||||
<em>Loading...</em>
|
<em>Loading...</em>
|
||||||
@ -14,7 +14,18 @@ else
|
|||||||
{
|
{
|
||||||
<TextEdit Placeholder="Search" Size="Size.Large" @bind-Text="@CustomFilterValue" />
|
<TextEdit Placeholder="Search" Size="Size.Large" @bind-Text="@CustomFilterValue" />
|
||||||
|
|
||||||
<DataGrid TItem="User" RowSelectable="@(u => false)" CustomFilter="@OnCustomFilter" Sortable="true" Editable="true" EditMode="DataGridEditMode.Popup" RowRemoving="RowDeletingCallback" Data="@Users" RowInserted="RowInsertedCallback" RowInserting="RowInsertingCallback" RowUpdating="RowUpdatingCallback">
|
<DataGrid
|
||||||
|
TItem="User"
|
||||||
|
RowSelectable="@(u => false)"
|
||||||
|
CustomFilter="@OnCustomFilter"
|
||||||
|
Sortable="true"
|
||||||
|
Editable="true"
|
||||||
|
EditMode="DataGridEditMode.Inline"
|
||||||
|
RowRemoving="RowDeletingCallback"
|
||||||
|
Data="@Members"
|
||||||
|
RowInserted="RowInsertedCallback"
|
||||||
|
RowInserting="RowInsertingCallback"
|
||||||
|
RowUpdating="RowUpdatingCallback">
|
||||||
<DataGridCommandColumn TItem="User">
|
<DataGridCommandColumn TItem="User">
|
||||||
<NewCommandTemplate>
|
<NewCommandTemplate>
|
||||||
<Button Color="Color.Success" Clicked="@context.Clicked" title="Create user">
|
<Button Color="Color.Success" Clicked="@context.Clicked" title="Create user">
|
||||||
@ -77,11 +88,10 @@ else
|
|||||||
var name = ((User) context ).Parent?.CommonName ?? "-";
|
var name = ((User) context ).Parent?.CommonName ?? "-";
|
||||||
@name
|
@name
|
||||||
}
|
}
|
||||||
|
|
||||||
</DisplayTemplate>
|
</DisplayTemplate>
|
||||||
<EditTemplate>
|
<EditTemplate>
|
||||||
<Select TValue="int?" SelectedValue="@((int?)(context.CellValue))" SelectedValueChanged="@(v => context.CellValue = v)" >
|
<Select TValue="int?" SelectedValue="@((int?)(context.CellValue))" SelectedValueChanged="@(v => context.CellValue = v)" >
|
||||||
@foreach (var item in OrganizationUnits)
|
@foreach (var item in OrganizationUnits ?? Enumerable.Empty<OrganizationUnit>())
|
||||||
{
|
{
|
||||||
<SelectItem TValue="int" Value="@(item.Id)">@item.CommonName</SelectItem>
|
<SelectItem TValue="int" Value="@(item.Id)">@item.CommonName</SelectItem>
|
||||||
}
|
}
|
||||||
|
@ -12,42 +12,40 @@ using UserService.Infrastructure.DataModels;
|
|||||||
|
|
||||||
namespace UserService.Pages
|
namespace UserService.Pages
|
||||||
{
|
{
|
||||||
public class UsersBase : ComponentBase
|
public class UsersBase : MembersBase<User>
|
||||||
{
|
{
|
||||||
[Inject] private IUsersRepository UsersRepository { get; set; } = null!;
|
[Inject] private IUsersRepository UsersRepository { get; set; } = null!;
|
||||||
[Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!;
|
[Inject] private IOrganizationUnitsRepository OrganizationUnitsRepository { get; set; } = null!;
|
||||||
|
|
||||||
[Inject] private IJSRuntime JsRuntime { get; set; } = null!;
|
[Inject] private IJSRuntime JsRuntime { get; set; } = null!;
|
||||||
|
|
||||||
protected IReadOnlyList<User>? Users { get; private set; }
|
|
||||||
protected IReadOnlyList<OrganizationUnit>? OrganizationUnits { get; private set; }
|
|
||||||
protected string? CustomFilterValue { get; set; }
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
Users = await UsersRepository.GetAllAsync().ConfigureAwait(false);
|
Members = await UsersRepository.GetAllAsync().ConfigureAwait(false);
|
||||||
OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false);
|
OrganizationUnits = await OrganizationUnitsRepository.GetAllAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task RowInsertingCallback(CancellableRowChange<User, Dictionary<string, object>> arg)
|
protected override async Task RowInsertingCallback(CancellableRowChange<User, Dictionary<string, object>> arg)
|
||||||
{
|
{
|
||||||
if (arg is null) throw new ArgumentNullException(nameof(arg));
|
if (arg is null) throw new ArgumentNullException(nameof(arg));
|
||||||
var mailValidation = Validators.ValidateEmail(arg.Values[nameof(User.EMail)]?.ToString());
|
var mailValidation = Validators.ValidateEmail(arg.Values[nameof(User.EMail)]?.ToString());
|
||||||
var commonNameValidation = Validators.ValidateCommonName(arg.Values[nameof(User.CommonName)]?.ToString(), Users);
|
var commonNameValidation = Validators.ValidateCommonName(arg.Values[nameof(User.CommonName)]?.ToString(),
|
||||||
|
Members ?? Enumerable.Empty<User>());
|
||||||
if (mailValidation == true && commonNameValidation == true) return;
|
if (mailValidation == true && commonNameValidation == true) return;
|
||||||
|
|
||||||
await JsRuntime.InvokeVoidAsync("alert", "User could not be added").ConfigureAwait(false);
|
await JsRuntime.InvokeVoidAsync("alert", "User could not be added").ConfigureAwait(false);
|
||||||
arg.Cancel = true;
|
arg.Cancel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task RowInsertedCallback(SavedRowItem<User, Dictionary<string, object>> arg)
|
protected override async Task RowInsertedCallback(SavedRowItem<User, Dictionary<string, object>> arg)
|
||||||
{
|
{
|
||||||
if (arg is null) throw new ArgumentNullException(nameof(arg));
|
if (arg is null) throw new ArgumentNullException(nameof(arg));
|
||||||
var user = arg.Item;
|
var user = arg.Item;
|
||||||
user.Parent = OrganizationUnits?.FirstOrDefault(x => x.Id == user.ParentId);
|
|
||||||
await UsersRepository.AddAsync(user).ConfigureAwait(false);
|
await UsersRepository.AddAsync(user).ConfigureAwait(false);
|
||||||
|
user.Parent = OrganizationUnits?.FirstOrDefault(x => x.Id == user.ParentId);
|
||||||
}
|
}
|
||||||
protected async Task RowDeletingCallback(CancellableRowChange<User> arg)
|
|
||||||
|
protected override async Task RowDeletingCallback(CancellableRowChange<User> arg)
|
||||||
{
|
{
|
||||||
if (arg == null) throw new ArgumentNullException(nameof(arg));
|
if (arg == null) throw new ArgumentNullException(nameof(arg));
|
||||||
var confirmed = await JsRuntime.InvokeAsync<bool>("confirm",
|
var confirmed = await JsRuntime.InvokeAsync<bool>("confirm",
|
||||||
@ -61,14 +59,6 @@ namespace UserService.Pages
|
|||||||
arg.Cancel = true;
|
arg.Cancel = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ValidateCommonName(ValidatorEventArgs e)
|
|
||||||
{
|
|
||||||
if (e == null) throw new ArgumentNullException(nameof(e));
|
|
||||||
var commonName = e.Value?.ToString();
|
|
||||||
var validationResult = Validators.ValidateCommonName(commonName, Users);
|
|
||||||
e.Status = validationResult == false ? ValidationStatus.Error : ValidationStatus.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void ValidateEmail(ValidatorEventArgs e)
|
protected static void ValidateEmail(ValidatorEventArgs e)
|
||||||
{
|
{
|
||||||
if (e == null) throw new ArgumentNullException(nameof(e));
|
if (e == null) throw new ArgumentNullException(nameof(e));
|
||||||
@ -82,25 +72,28 @@ namespace UserService.Pages
|
|||||||
_ => ValidationStatus.Success
|
_ => ValidationStatus.Success
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
protected async Task RowUpdatingCallback(CancellableRowChange<User, Dictionary<string, object>> arg)
|
|
||||||
|
protected override async Task RowUpdatingCallback(CancellableRowChange<User, Dictionary<string, object>> arg)
|
||||||
{
|
{
|
||||||
if (arg == null) throw new ArgumentNullException(nameof(arg));
|
if (arg == null) throw new ArgumentNullException(nameof(arg));
|
||||||
var user = arg.Item;
|
var user = arg.Item;
|
||||||
user.Parent = OrganizationUnits.FirstOrDefault(x => x.Id == (int?)arg.Values[nameof(Node.ParentId)]);
|
user.MapFields(arg.Values);
|
||||||
|
user.Parent = OrganizationUnits?.FirstOrDefault(x => x.Id == (int?) arg.Values[nameof(Node.ParentId)]);
|
||||||
var result = await UsersRepository.UpdateAsync(user).ConfigureAwait(false);
|
var result = await UsersRepository.UpdateAsync(user).ConfigureAwait(false);
|
||||||
arg.Cancel = !result;
|
arg.Cancel = !result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool OnCustomFilter(User model)
|
protected override bool OnCustomFilter(User model)
|
||||||
{
|
{
|
||||||
|
if (model == null) throw new ArgumentNullException(nameof(model));
|
||||||
// We want to accept empty value as valid or otherwise
|
// We want to accept empty value as valid or otherwise
|
||||||
// datagrid will not show anything.
|
// datagrid will not show anything.
|
||||||
if (string.IsNullOrEmpty(CustomFilterValue) || CustomFilterValue.Length < 3) return true;
|
if (string.IsNullOrEmpty(CustomFilterValue) || CustomFilterValue.Length < 3) return true;
|
||||||
|
|
||||||
return
|
return
|
||||||
model?.FirstName?.Contains(CustomFilterValue, StringComparison.OrdinalIgnoreCase) == true
|
model.FirstName?.Contains(CustomFilterValue, StringComparison.OrdinalIgnoreCase) == true
|
||||||
|| model?.LastName?.Contains(CustomFilterValue, StringComparison.OrdinalIgnoreCase) == true
|
|| model.LastName?.Contains(CustomFilterValue, StringComparison.OrdinalIgnoreCase) == true
|
||||||
|| model?.CommonName?.Contains(CustomFilterValue, StringComparison.OrdinalIgnoreCase) == true;
|
|| model.CommonName.Contains(CustomFilterValue, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user