GlobalEntities now can be added not nice but added
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
@inject ApplicationDbContext CouchLogDB
|
@inject ApplicationDbContext CouchLogDB
|
||||||
@inject UserManager<ApplicationUser> UserManager
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
|
|
||||||
@@ -17,29 +18,44 @@
|
|||||||
<div class="container-fluid mt-4">
|
<div class="container-fluid mt-4">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
<h2>Global List</h2>
|
<h2>Global List</h2>
|
||||||
<button class="btn btn-primary" type="button" @onclick="ToogleCollapseNewGlobalEntity">@(isCollapseNewGlobalEntityOpen ? "X" : "Add Entity")</button>
|
<button class="btn btn-info" type="button" @onclick="ToogleCollapseNewGlobalEntity">@(isCollapseNewGlobalEntityOpen ? "X" : "Add Entity")</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse @(isCollapseNewGlobalEntityOpen ? "show" : "")" id="CollapseCreateNewGlobalEntity">
|
<div class="collapse @(isCollapseNewGlobalEntityOpen ? "show" : "")" id="CollapseCreateNewGlobalEntity">
|
||||||
<div class="mb-4 align-items-center CreateNewGlobalEntity-Container">
|
<div class="mb-4 align-items-center CreateNewGlobalEntity-Container">
|
||||||
<EditForm Model="@GlobalEntity" OnSubmit="CreateNewGlobalEntity" FormName="CreateNewGlobalEntityForm">
|
<EditForm Model="@GlobalEntity" OnSubmit="CreateNewGlobalEntity" FormName="CreateNewGlobalEntityForm">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
<ValidationSummary />
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="Title" class="form-label">Title</label>
|
<label for="Title" class="form-label">Title</label>
|
||||||
<InputText id="Title" class="form-control" @bind-Value="GlobalEntity.Title"></InputText>
|
<InputText id="Title" class="form-control" @bind-Value="GlobalEntity.Title"></InputText>
|
||||||
<ValidationMessage For="@(() => GlobalEntity.Title)"></ValidationMessage>
|
<ValidationMessage For="@(() => GlobalEntity.Title)"></ValidationMessage>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="Type" class="form-label">Type</label>
|
<label for="Type" class="form-label">Type</label>
|
||||||
<select>
|
<select id="Type" class="form-select" @bind="SelectedMediaTypeId">
|
||||||
@foreach(MediaType Type in MediaTypes)
|
@foreach(MediaType Type in MediaTypes)
|
||||||
{
|
{
|
||||||
<option value="@Type.Id">@Type.Name</option>
|
<option value="@Type.Id">@Type.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
<button type="submit">Create new Global Entity</button>
|
<label for="Picture" class="form-label">Picture</label>
|
||||||
|
<InputFile OnChange="@LoadFiles" accept="image/*"/>
|
||||||
|
@if (!string.IsNullOrEmpty(ImagePreviewUrl))
|
||||||
|
{
|
||||||
|
<img src="@ImagePreviewUrl" style="max-width: 256px; max-height: 256px;" />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="Genres" class="form-label">Genres</label>
|
||||||
|
@foreach(Genre Genre in Genres)
|
||||||
|
{
|
||||||
|
<button class="btn-primary btn me-2" value="@Genre.Id" type="button" @onclick="() => AddGenreToList(Genre.Id)">@Genre.Name</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn-success btn">Create new Global Entity</button>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,6 +64,29 @@
|
|||||||
{
|
{
|
||||||
<div name="Enity-Container" class="col-12 col-md-6 col-lg-3 mb-4 Entity-Container">
|
<div name="Enity-Container" class="col-12 col-md-6 col-lg-3 mb-4 Entity-Container">
|
||||||
<div name="Entity-Container-Card" class="Entity-Container-Card">
|
<div name="Entity-Container-Card" class="Entity-Container-Card">
|
||||||
|
<div class="Entity-Container-Menu-Button">
|
||||||
|
<button type="button" class="Entity-Container-Menu-Button" data-bs-toogle="modal" data-bs-target="@Entity.Id">⋮</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="@Entity.Id" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="staticBackdropLabel">Modal title</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
This is a vertically centered modal.
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary">Understood</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div name="Enity-Container-Image" class="">
|
<div name="Enity-Container-Image" class="">
|
||||||
<a href="javascript:void(0)" class="Entity-Container-Image">
|
<a href="javascript:void(0)" class="Entity-Container-Image">
|
||||||
<img src="@Entity.PicturePath" alt="" class="Entity-Container-Image" />
|
<img src="@Entity.PicturePath" alt="" class="Entity-Container-Image" />
|
||||||
@@ -57,10 +96,10 @@
|
|||||||
<h3 class="">@Entity.Title</h3>
|
<h3 class="">@Entity.Title</h3>
|
||||||
</div>
|
</div>
|
||||||
<div name="Entity-Container-Button" class="d-flex Entity-Container-Button" style="gap: 10px;">
|
<div name="Entity-Container-Button" class="d-flex Entity-Container-Button" style="gap: 10px;">
|
||||||
<button class="btn btn-primary" type="button" @onclick="() => AddToPrivateList(Entity)">
|
<button class="btn btn-info" type="button" @onclick="() => AddToPrivateList(Entity)">
|
||||||
@(IsInPrivateList(Entity.Id) ? "Added" : "Add to Private List")
|
@(IsInPrivateList(Entity.Id) ? "Added" : "Add to Private List")
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary" type="button">Add to Shared List</button>
|
<button class="btn btn-info" type="button" @onclick="() => throw new NotImplementedException()">Add to Shared List</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,18 +110,33 @@
|
|||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private List<MediaType> MediaTypes = new List<MediaType>();
|
private List<MediaType> MediaTypes = new List<MediaType>();
|
||||||
public List<GlobalEntity> GlobalEntities = new List<GlobalEntity>();
|
private List<Genre> Genres = new List<Genre>();
|
||||||
|
private List<GlobalEntity> GlobalEntities = new List<GlobalEntity>();
|
||||||
|
private List<int> GenreIds = new List<int>();
|
||||||
private HashSet<int> UserPrivateEntityIds = new();
|
private HashSet<int> UserPrivateEntityIds = new();
|
||||||
|
private string? ImagePreviewUrl;
|
||||||
|
private IBrowserFile? Picture;
|
||||||
|
System.Security.Claims.ClaimsPrincipal User = new();
|
||||||
|
ApplicationUser? AppUser = new();
|
||||||
|
private GlobalEntity GlobalEntity = new();
|
||||||
|
private bool isCollapseNewGlobalEntityOpen = false;
|
||||||
|
private int SelectedMediaTypeId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
GlobalEntities = await CouchLogDB.GlobalEntities.OrderByDescending(Entity => Entity.Id).ToListAsync();
|
GlobalEntities = await CouchLogDB.GlobalEntities.OrderByDescending(Entity => Entity.Id).ToListAsync();
|
||||||
MediaTypes = await CouchLogDB.MediaType.OrderByDescending(Type => Type.Id).ToListAsync();
|
MediaTypes = await CouchLogDB.MediaType.OrderBy(Type => Type.Id).ToListAsync();
|
||||||
|
Genres = await CouchLogDB.Genres.OrderBy(Genre => Genre.Id).ToListAsync();
|
||||||
|
|
||||||
var AuthState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
var AuthState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
var User = AuthState.User;
|
User = AuthState.User;
|
||||||
|
|
||||||
var AppUser = await UserManager.GetUserAsync(User);
|
AppUser = await UserManager.GetUserAsync(User);
|
||||||
|
|
||||||
if (AppUser == null)
|
if (AppUser == null)
|
||||||
{
|
{
|
||||||
@@ -97,41 +151,102 @@
|
|||||||
UserPrivateEntityIds = TempUserPrivateEntityIds.ToHashSet();
|
UserPrivateEntityIds = TempUserPrivateEntityIds.ToHashSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task LoadFiles(InputFileChangeEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
Picture = eventArgs.File;
|
||||||
|
|
||||||
|
//Byte[] Buffer = new byte[Picture.Size];
|
||||||
|
//await Picture.OpenReadStream().ReadAsync(Buffer);
|
||||||
|
//await Picture.OpenReadStream(maxAllowedSize: 10_000_000).ReadAsync(Buffer);
|
||||||
|
|
||||||
private bool isCollapseNewGlobalEntityOpen = false;
|
//string Base64 = Convert.ToBase64String(Buffer);
|
||||||
|
//ImagePreviewUrl = $"data:{Picture.ContentType};base64,{Base64}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
private void ToogleCollapseNewGlobalEntity()
|
private void ToogleCollapseNewGlobalEntity()
|
||||||
{
|
{
|
||||||
isCollapseNewGlobalEntityOpen = !isCollapseNewGlobalEntityOpen;
|
isCollapseNewGlobalEntityOpen = !isCollapseNewGlobalEntityOpen;
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private GlobalEntity GlobalEntity = new();
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
private void CreateNewGlobalEntity()
|
/// <returns></returns>
|
||||||
|
private async Task CreateNewGlobalEntity()
|
||||||
{
|
{
|
||||||
|
if (Picture is null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No Picture selected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AppUser is null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("User not loaded or not logged in.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Save Picture and Name it
|
||||||
|
string NewFileName = $"{GlobalEntity.Title.Replace(" ", "_")}_{Guid.NewGuid()}{Path.GetExtension(Picture.Name)}";
|
||||||
|
string PicturePath = Path.Combine("wwwroot", "Pictures", NewFileName);
|
||||||
|
using FileStream FileStream = File.Create(PicturePath);
|
||||||
|
await Picture.OpenReadStream().CopyToAsync(FileStream);
|
||||||
|
//await Picture.OpenReadStream(maxAllowedSize: 10_000_000).CopyToAsync(FileStream);
|
||||||
|
|
||||||
|
GlobalEntity.PicturePath = $"Pictures/{NewFileName}";
|
||||||
|
GlobalEntity.CreatorId = AppUser.Id;
|
||||||
|
GlobalEntity.TypeId = SelectedMediaTypeId;
|
||||||
|
GlobalEntity.CreationTime = DateTime.Now;
|
||||||
|
|
||||||
|
CouchLogDB.Add(GlobalEntity);
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
|
||||||
|
foreach(int GenreId in GenreIds)
|
||||||
|
{
|
||||||
|
LinkTableGlobalGenre LinkTableGlobalGenre = new() { GenreId = GenreId, GlobalEntityId = GlobalEntity.Id };
|
||||||
|
CouchLogDB.Add(LinkTableGlobalGenre);
|
||||||
|
}
|
||||||
|
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="GolbalEntityId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
private bool IsInPrivateList(int GolbalEntityId)
|
private bool IsInPrivateList(int GolbalEntityId)
|
||||||
{
|
{
|
||||||
return UserPrivateEntityIds.Contains(GolbalEntityId);
|
return UserPrivateEntityIds.Contains(GolbalEntityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="GlobalEntity"></param>
|
||||||
|
/// <returns></returns>
|
||||||
private async Task AddToPrivateList(GlobalEntity GlobalEntity)
|
private async Task AddToPrivateList(GlobalEntity GlobalEntity)
|
||||||
{
|
{
|
||||||
var AuthState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
|
||||||
var User = AuthState.User;
|
|
||||||
|
|
||||||
if(User.Identity?.IsAuthenticated == true)
|
if(User.Identity?.IsAuthenticated == true)
|
||||||
{
|
{
|
||||||
//var AppUser = await UserManager.GetUserAsync(User);
|
|
||||||
if(!IsInPrivateList(GlobalEntity.Id))
|
if(!IsInPrivateList(GlobalEntity.Id))
|
||||||
{
|
{
|
||||||
|
if (AppUser is null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("User not loaded or not logged in.");
|
||||||
|
}
|
||||||
|
|
||||||
PrivateEntity PrivateEntity = new()
|
PrivateEntity PrivateEntity = new()
|
||||||
{
|
{
|
||||||
UserId = (await UserManager.GetUserAsync(User))!.Id,
|
UserId = AppUser.Id,
|
||||||
CreationTime = DateTime.Now,
|
CreationTime = DateTime.Now,
|
||||||
GlobalEntityId = GlobalEntity.Id,
|
GlobalEntityId = GlobalEntity.Id,
|
||||||
};
|
};
|
||||||
@@ -144,4 +259,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddGenreToList(int GenreId)
|
||||||
|
{
|
||||||
|
if (!GenreIds.Contains(GenreId))
|
||||||
|
{
|
||||||
|
GenreIds.Add(GenreId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -75,3 +75,14 @@
|
|||||||
background: #111;
|
background: #111;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Entity-Container-Menu-Button {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
right: 7.5px;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #0dcaf0;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<PackAsTool>True</PackAsTool>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Binary file not shown.
@@ -10,7 +10,7 @@ namespace CouchLog.Data
|
|||||||
[Key]
|
[Key]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required (ErrorMessage = "Title is required")]
|
||||||
[MaxLength(200)]
|
[MaxLength(200)]
|
||||||
public required string Title { get; set; }
|
public required string Title { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,38 @@ namespace CouchLog
|
|||||||
this.CouchLogDB = CouchLogDB;
|
this.CouchLogDB = CouchLogDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddBasicGenresToDatabase()
|
||||||
|
{
|
||||||
|
List<Genre> ExistingGenres = CouchLogDB.Genres.OrderByDescending(Genre => Genre.Id).ToList();
|
||||||
|
|
||||||
|
List<Genre> Genres = new List<Genre>
|
||||||
|
{
|
||||||
|
new() { Name = "Action", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Animation", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Comedy", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Crime", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Drama", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Fantasy", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "History", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Horror", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Musical", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Miniseries", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Mystery", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Romance", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Science Fiction", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Thriller", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "War", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Western", CreationTime = DateTime.Now },
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (Genre Genre in Genres)
|
||||||
|
{
|
||||||
|
CouchLogDB.Add(Genre);
|
||||||
|
}
|
||||||
|
|
||||||
|
CouchLogDB.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public void AddBasicDatabaseEntries()
|
public void AddBasicDatabaseEntries()
|
||||||
{
|
{
|
||||||
//##################
|
//##################
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using CouchLog.Components;
|
using CouchLog.Components;
|
||||||
using CouchLog.Components.Account;
|
using CouchLog.Components.Account;
|
||||||
using CouchLog.Data;
|
using CouchLog.Data;
|
||||||
|
using CouchLog;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -145,8 +146,9 @@ using (var scope = app.Services.CreateScope())
|
|||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
|
||||||
|
//OnStartUp onStartUp = new(CouchLogDB);
|
||||||
|
//onStartUp.AddBasicGenresToDatabase();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("ALL UP");
|
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
Reference in New Issue
Block a user