Compare commits
82 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ac9fb7e81 | |||
| a4d7269f8f | |||
| c7d741d15b | |||
| 6d2a6c5925 | |||
| 9ccb929553 | |||
| 5e086c0598 | |||
| a7c86289b3 | |||
| b2e851d765 | |||
| 1a1d7dec7c | |||
| 103da6abe8 | |||
| 5f2fdbac87 | |||
| e0ceb7d314 | |||
| 8df80eba3b | |||
| 77875110f0 | |||
| ddbc6affd1 | |||
| cd41eea0d9 | |||
| d15ecd926c | |||
| 78774abffd | |||
| a8cc182265 | |||
| 65e03c2586 | |||
| 45c4379d53 | |||
| 55d65f4841 | |||
| 3f4feb9dc9 | |||
| 45479d9df7 | |||
| 1d077fe1cc | |||
| 2046939d8a | |||
| 02d2a26a82 | |||
| c00fb3234c | |||
| 6922303e52 | |||
| 3ffad3abbe | |||
| 68afe22526 | |||
| 28fe48c3f0 | |||
| 8cd0dc6c81 | |||
| 8c4a3def23 | |||
| ef41d46e50 | |||
| f8eba6b8dd | |||
| 99581df6f7 | |||
| 6991af3daa | |||
| 04ca70dc67 | |||
| cd159509a0 | |||
| ea7604a05f | |||
| 622a751c40 | |||
| 0f3da6952b | |||
| 59442d5203 | |||
| 94e3104773 | |||
| dcbff4e30d | |||
| 7af23518e5 | |||
| 226cc38bf7 | |||
| 8e615c15f0 | |||
| 352a7dbfde | |||
| 2e9ea45bd9 | |||
| e7f8e8c331 | |||
| 9fab942181 | |||
| b316a882c5 | |||
| 594541a103 | |||
| ee7bcc1eae | |||
| 4fe354add0 | |||
| 44cbfc9c55 | |||
| c6355d47df | |||
| 97a92269ad | |||
| 66468a1f8b | |||
| e48e8b6394 | |||
| 5f39417109 | |||
| 76e8e8daa6 | |||
| 6db2bca50b | |||
| 46491dd987 | |||
| 8edf749e23 | |||
| 3cc4fd8240 | |||
| d0f91fd0e1 | |||
| f1a68296ec | |||
| c5a3ba2b40 | |||
| 67b559e6d7 | |||
| 3c10721c4e | |||
| eec7f40e72 | |||
| 899a36a49c | |||
| 8e607ee180 | |||
| 87e6132f34 | |||
| dd845f4be6 | |||
| 6ca8fe7bdc | |||
| 56bcd712f1 | |||
| 4e3eca0650 | |||
| 2160c9abbc |
@@ -24,13 +24,6 @@ jobs:
|
|||||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||||
echo "REPO_LC=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
|
echo "REPO_LC=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Login to own image registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: gitea.penry.de
|
|
||||||
username: ${{ secrets.REGISTRY_USER }}
|
|
||||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Setup .NET10
|
- name: Setup .NET10
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
@@ -42,8 +35,16 @@ jobs:
|
|||||||
-t gitea.penry.de/${{ env.REPO_LC }}:${{ env.VERSION }} \
|
-t gitea.penry.de/${{ env.REPO_LC }}:${{ env.VERSION }} \
|
||||||
-t gitea.penry.de/${{ env.REPO_LC }}:latest \
|
-t gitea.penry.de/${{ env.REPO_LC }}:latest \
|
||||||
--label "org.opencontainers.image.source=https://gitea.penry.de/${{ github.repository }}" \
|
--label "org.opencontainers.image.source=https://gitea.penry.de/${{ github.repository }}" \
|
||||||
|
--build-arg VERSION=${{ env.VERSION }} \
|
||||||
.
|
.
|
||||||
|
|
||||||
|
- name: Login to own image registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: gitea.penry.de
|
||||||
|
username: ${{ secrets.REGISTRY_USER }}
|
||||||
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
|
||||||
- name: Push Images
|
- name: Push Images
|
||||||
run: |
|
run: |
|
||||||
docker push gitea.penry.de/${{ env.REPO_LC }}:${{ env.VERSION }}
|
docker push gitea.penry.de/${{ env.REPO_LC }}:${{ env.VERSION }}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: Build Docker Linux ARM64
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
#- main
|
- main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-docker-linux-arm64:
|
build-docker-linux-arm64:
|
||||||
@@ -14,15 +14,66 @@ jobs:
|
|||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup Docker Buildx
|
- name: Setup Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Get Repository Name
|
||||||
|
id: get_repo
|
||||||
|
run: |
|
||||||
|
REPO_LC="${GITHUB_REPOSITORY,,}"
|
||||||
|
echo "REPO_LC=$REPO_LC" >> $GITHUB_ENV
|
||||||
|
echo "Repo: $REPO_LC"
|
||||||
|
|
||||||
|
- name: Build version
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
LAST_TAG=$(git describe --tags --abbrev=0)
|
||||||
|
|
||||||
|
if [[ -z "${LAST_TAG:-}" ]]; then
|
||||||
|
echo "No tag found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMMIT_COUNT=$(git rev-list $LAST_TAG..HEAD --count)
|
||||||
|
|
||||||
|
if [[ "$LAST_TAG" == *-* ]]; then
|
||||||
|
TEMP_LAST_TAG="${LAST_TAG%-*}"
|
||||||
|
VERSION="${TEMP_LAST_TAG}-nightly.${COMMIT_COUNT}"
|
||||||
|
else
|
||||||
|
VERSION="${LAST_TAG}-nightly.${COMMIT_COUNT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "LAST_TAG=$LAST_TAG" >> "$GITHUB_ENV"
|
||||||
|
echo "COMMIT_COUNT=$COMMIT_COUNT" >> "$GITHUB_ENV"
|
||||||
|
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
echo "Last tag: $LAST_TAG"
|
||||||
|
echo "Commit count: $COMMIT_COUNT"
|
||||||
|
echo "Final version: $VERSION"
|
||||||
|
|
||||||
- name: Build Linux ARM64 Docker Image
|
- name: Build Linux ARM64 Docker Image
|
||||||
run: docker build -t couchlog-linux-arm64 .
|
run: |
|
||||||
|
docker build \
|
||||||
|
-t gitea.penry.de/${{ env.REPO_LC }}:nightly \
|
||||||
|
--build-arg VERSION=${{ env.VERSION }} \
|
||||||
|
.
|
||||||
|
|
||||||
|
- name: Login to own image registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: gitea.penry.de
|
||||||
|
username: ${{ secrets.REGISTRY_USER }}
|
||||||
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Push Images
|
||||||
|
run: |
|
||||||
|
docker push gitea.penry.de/${{ env.REPO_LC }}:nightly
|
||||||
|
|
||||||
- name: Save Docker Image to Tar
|
- name: Save Docker Image to Tar
|
||||||
run: docker save -o CouchLog-Linux-ARM64-Docker-Image.tar couchlog-linux-arm64
|
run: docker save -o CouchLog-Linux-ARM64-Docker-Image.tar gitea.penry.de/${{ env.REPO_LC }}:nightly
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@@ -30,4 +81,4 @@ jobs:
|
|||||||
name: CouchLog-Linux-ARM64-Docker-Image
|
name: CouchLog-Linux-ARM64-Docker-Image
|
||||||
path: CouchLog-Linux-ARM64-Docker-Image.tar
|
path: CouchLog-Linux-ARM64-Docker-Image.tar
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
retention-days: 1
|
retention-days: 5
|
||||||
@@ -2,5 +2,7 @@
|
|||||||
bin
|
bin
|
||||||
Debug
|
Debug
|
||||||
/CouchLog/Data/CouchLog.db
|
/CouchLog/Data/CouchLog.db
|
||||||
|
/CouchLog/Data/CouchLog.db-shm
|
||||||
|
/CouchLog/Data/CouchLog.db-wal
|
||||||
#Migrations
|
#Migrations
|
||||||
obj
|
obj
|
||||||
|
|||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"terminal.explorerKind": "integrated"
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
[*.cs]
|
||||||
|
|
||||||
|
# IDE0130: Namespace does not match folder structure
|
||||||
|
dotnet_diagnostic.IDE0130.severity = none
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
@page "/Account/Login"
|
@page "/Account/Login"
|
||||||
|
@layout Layout.IdentityLayout
|
||||||
|
|
||||||
@using System.ComponentModel.DataAnnotations
|
@using System.ComponentModel.DataAnnotations
|
||||||
@using Microsoft.AspNetCore.Authentication
|
@using Microsoft.AspNetCore.Authentication
|
||||||
@using Microsoft.AspNetCore.Identity
|
@using Microsoft.AspNetCore.Identity
|
||||||
@using CouchLog.Data
|
@using CouchLog.Data
|
||||||
|
@using MudBlazor
|
||||||
|
|
||||||
@inject SignInManager<ApplicationUser> SignInManager
|
@inject SignInManager<ApplicationUser> SignInManager
|
||||||
@inject ILogger<Login> Logger
|
@inject ILogger<Login> Logger
|
||||||
@@ -12,57 +14,59 @@
|
|||||||
|
|
||||||
<PageTitle>Log in</PageTitle>
|
<PageTitle>Log in</PageTitle>
|
||||||
|
|
||||||
<h1>Log in</h1>
|
<MudGrid Justify="Justify.Center" Class="align-center">
|
||||||
<div class="row">
|
@* Linke Spalte: Login-Formular *@
|
||||||
<div class="col-lg-6">
|
<MudItem xs="12" md="7">
|
||||||
<section>
|
<MudPaper Elevation="3" Class="pa-6">
|
||||||
<StatusMessage Message="@errorMessage" />
|
<StatusMessage Message="@errorMessage" />
|
||||||
|
|
||||||
<EditForm Model="Input" method="post" OnValidSubmit="LoginUser" FormName="login">
|
<EditForm Model="Input" method="post" OnValidSubmit="LoginUser" FormName="login">
|
||||||
<DataAnnotationsValidator />
|
<DataAnnotationsValidator />
|
||||||
<h2>Use a local account to log in.</h2>
|
|
||||||
<hr />
|
<MudText Typo="Typo.h5" GutterBottom="true" Align="Align.Center">Login</MudText>
|
||||||
|
<MudDivider Class="mb-6" />
|
||||||
|
|
||||||
<ValidationSummary class="text-danger" role="alert" />
|
<ValidationSummary class="text-danger" role="alert" />
|
||||||
<div class="form-floating mb-3">
|
|
||||||
<InputText @bind-Value="Input.Username" id="Input.Username" class="form-control" autocomplete="username" aria-required="true" placeholder="Username" />
|
@* MudTextFields zwingend mit Name-Attribut für SSR *@
|
||||||
<label for="Input.Username" class="form-label">Username</label>
|
<MudTextField @bind-Value="Input.Username"
|
||||||
<ValidationMessage For="() => Input.Username" class="text-danger" />
|
For="@(() => Input.Username)"
|
||||||
|
Name="Input.Username"
|
||||||
|
Label="Username"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Margin="Margin.Dense"
|
||||||
|
ShrinkLabel="true"
|
||||||
|
Class="mb-4" />
|
||||||
|
|
||||||
|
<MudTextField @bind-Value="Input.Password"
|
||||||
|
For="@(() => Input.Password)"
|
||||||
|
Name="Input.Password"
|
||||||
|
Label="Password"
|
||||||
|
InputType="InputType.Password"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Margin="Margin.Dense"
|
||||||
|
ShrinkLabel="true"
|
||||||
|
Class="mb-4" />
|
||||||
|
|
||||||
|
@* Standard-Checkbox mit MudBlazor-Typografie *@
|
||||||
|
<div class="d-flex align-center mb-6">
|
||||||
|
<InputCheckbox @bind-Value="Input.RememberMe" id="Input.RememberMe" style="width: 1.2rem; height: 1.2rem; accent-color: var(--mud-palette-primary);" />
|
||||||
|
<label for="Input.RememberMe" class="ml-2 mud-typography mud-typography-body1">Remember me</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-floating mb-3">
|
|
||||||
<InputText type="password" @bind-Value="Input.Password" id="Input.Password" class="form-control" autocomplete="current-password" aria-required="true" placeholder="Password" />
|
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" Size="Size.Large" FullWidth="true" Class="mb-4">
|
||||||
<label for="Input.Password" class="form-label">Password</label>
|
Log in
|
||||||
<ValidationMessage For="() => Input.Password" class="text-danger" />
|
</MudButton>
|
||||||
</div>
|
|
||||||
<div class="checkbox mb-3">
|
<div class="d-flex flex-column gap-2 mt-4">
|
||||||
<label class="form-label">
|
<MudLink Href="Account/ForgotPassword" Typo="Typo.body2">Forgot your password?</MudLink>
|
||||||
<InputCheckbox @bind-Value="Input.RememberMe" class="darker-border-checkbox form-check-input" />
|
<MudLink Href="@(NavigationManager.GetUriWithQueryParameters("Account/Register", new Dictionary<string, object?> { ["ReturnUrl"] = ReturnUrl }))" Typo="Typo.body2">Register as a new user</MudLink>
|
||||||
Remember me
|
<MudLink Href="Account/ResendEmailConfirmation" Typo="Typo.body2">Resend email confirmation</MudLink>
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<a href="Account/ForgotPassword">Forgot your password?</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="@(NavigationManager.GetUriWithQueryParameters("Account/Register", new Dictionary<string, object?> { ["ReturnUrl"] = ReturnUrl }))">Register as a new user</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="Account/ResendEmailConfirmation">Resend email confirmation</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</EditForm>
|
</EditForm>
|
||||||
</section>
|
</MudPaper>
|
||||||
</div>
|
</MudItem>
|
||||||
<div class="col-lg-4 col-lg-offset-2">
|
</MudGrid>
|
||||||
<section>
|
|
||||||
<h3>Use another service to log in.</h3>
|
|
||||||
<hr />
|
|
||||||
<ExternalLoginPicker />
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string? errorMessage;
|
private string? errorMessage;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@page "/Account/Register"
|
@page "/Account/Register"
|
||||||
|
@layout Layout.IdentityLayout
|
||||||
|
|
||||||
@using System.ComponentModel.DataAnnotations
|
@using System.ComponentModel.DataAnnotations
|
||||||
@using System.Text
|
@using System.Text
|
||||||
@@ -10,10 +11,10 @@
|
|||||||
@inject UserManager<ApplicationUser> UserManager
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
@inject IUserStore<ApplicationUser> UserStore
|
@inject IUserStore<ApplicationUser> UserStore
|
||||||
@inject SignInManager<ApplicationUser> SignInManager
|
@inject SignInManager<ApplicationUser> SignInManager
|
||||||
@inject IEmailSender<ApplicationUser> EmailSender
|
|
||||||
@inject ILogger<Register> Logger
|
@inject ILogger<Register> Logger
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IdentityRedirectManager RedirectManager
|
@inject IdentityRedirectManager RedirectManager
|
||||||
|
@inject ApplicationDbContext CouchLogDB
|
||||||
|
|
||||||
<PageTitle>Register</PageTitle>
|
<PageTitle>Register</PageTitle>
|
||||||
|
|
||||||
@@ -28,9 +29,9 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<ValidationSummary class="text-danger" role="alert" />
|
<ValidationSummary class="text-danger" role="alert" />
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
<InputText @bind-Value="Input.Email" id="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
|
<InputText @bind-Value="Input.Username" id="Input.Username" class="form-control" autocomplete="username" aria-required="true" placeholder="NewUsername" />
|
||||||
<label for="Input.Email">Email</label>
|
<label for="Input.Username">Username</label>
|
||||||
<ValidationMessage For="() => Input.Email" class="text-danger" />
|
<ValidationMessage For="() => Input.Username" class="text-danger" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
<InputText type="password" @bind-Value="Input.Password" id="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
|
<InputText type="password" @bind-Value="Input.Password" id="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
|
||||||
@@ -67,11 +68,19 @@
|
|||||||
|
|
||||||
public async Task RegisterUser(EditContext editContext)
|
public async Task RegisterUser(EditContext editContext)
|
||||||
{
|
{
|
||||||
|
if(!CouchLogDB.AccountsSettings.First().IsRegistrationAllowed)
|
||||||
|
{
|
||||||
|
identityErrors = new[]
|
||||||
|
{
|
||||||
|
new IdentityError { Description = "Registration is deactivated" }
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var user = CreateUser();
|
var user = CreateUser();
|
||||||
|
|
||||||
await UserStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
|
await UserStore.SetUserNameAsync(user, Input.Username, CancellationToken.None);
|
||||||
var emailStore = GetEmailStore();
|
user.EmailConfirmed = true;
|
||||||
await emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
|
|
||||||
var result = await UserManager.CreateAsync(user, Input.Password);
|
var result = await UserManager.CreateAsync(user, Input.Password);
|
||||||
|
|
||||||
if (!result.Succeeded)
|
if (!result.Succeeded)
|
||||||
@@ -80,23 +89,24 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.LogInformation("User created a new account with password.");
|
if(CouchLogDB.CouchLogState.Count() == 0)
|
||||||
|
|
||||||
var userId = await UserManager.GetUserIdAsync(user);
|
|
||||||
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
|
|
||||||
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
|
||||||
var callbackUrl = NavigationManager.GetUriWithQueryParameters(
|
|
||||||
NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri,
|
|
||||||
new Dictionary<string, object?> { ["userId"] = userId, ["code"] = code, ["returnUrl"] = ReturnUrl });
|
|
||||||
|
|
||||||
await EmailSender.SendConfirmationLinkAsync(user, Input.Email, HtmlEncoder.Default.Encode(callbackUrl));
|
|
||||||
|
|
||||||
if (UserManager.Options.SignIn.RequireConfirmedAccount)
|
|
||||||
{
|
{
|
||||||
RedirectManager.RedirectTo(
|
await UserManager.AddToRoleAsync(user, "Admin");
|
||||||
"Account/RegisterConfirmation",
|
await CouchLogDB.CouchLogState.AddAsync(new CouchLogState
|
||||||
new() { ["email"] = Input.Email, ["returnUrl"] = ReturnUrl });
|
{
|
||||||
|
Id = 1,
|
||||||
|
InitializationDate = DateTime.Now,
|
||||||
|
IsInitialized = true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await UserManager.AddToRoleAsync(user, "User");
|
||||||
|
}
|
||||||
|
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
|
||||||
|
Logger.LogInformation("User created a new account with password.");
|
||||||
|
|
||||||
await SignInManager.SignInAsync(user, isPersistent: false);
|
await SignInManager.SignInAsync(user, isPersistent: false);
|
||||||
RedirectManager.RedirectTo(ReturnUrl);
|
RedirectManager.RedirectTo(ReturnUrl);
|
||||||
@@ -127,9 +137,8 @@
|
|||||||
private sealed class InputModel
|
private sealed class InputModel
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
[EmailAddress]
|
[Display(Name = "Username")]
|
||||||
[Display(Name = "Email")]
|
public string Username { get; set; } = "";
|
||||||
public string Email { get; set; } = "";
|
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
@page "/AdminSettings/CouchLogSettings"
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
@using System.Reflection
|
||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
|
||||||
|
@inject ApplicationDbContext CouchLogDb
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h3">CouchLog Settings</MudText>
|
||||||
|
|
||||||
|
<EditForm Model="_accountsSettings">
|
||||||
|
<MudSwitch T="bool"
|
||||||
|
Label="Is Registration allowed"
|
||||||
|
Value="_accountsSettings.IsRegistrationAllowed"
|
||||||
|
ValueChanged="OnRegistrationChanged"
|
||||||
|
Color="Color.Primary" />
|
||||||
|
</EditForm>
|
||||||
|
|
||||||
|
<MudText>Version: @_version</MudText>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private AccountsSettings? _accountsSettings;
|
||||||
|
private readonly string _version = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion?.Split('+')[0];
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
_accountsSettings = await CouchLogDb.AccountsSettings.FirstAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnRegistrationChanged(bool value)
|
||||||
|
{
|
||||||
|
_accountsSettings!.IsRegistrationAllowed = value;
|
||||||
|
|
||||||
|
CouchLogDb.AccountsSettings.Update(_accountsSettings);
|
||||||
|
await CouchLogDb.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
|
||||||
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
|
@inject ISnackbar Snackbar
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<TitleContent>
|
||||||
|
<MudText Typo="Typo.h6">Create New User</MudText>
|
||||||
|
</TitleContent>
|
||||||
|
|
||||||
|
<DialogContent>
|
||||||
|
<MudInput @bind-Value="@_newUsername"></MudInput>
|
||||||
|
<MudSelect @bind-Value="_newUserRole">
|
||||||
|
@foreach (var role in Roles)
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@role.Name">@role.Name</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="CreateNewUser" Variant="Variant.Filled" Color="Color.Success">Create user</MudButton>
|
||||||
|
<MudButton OnClick="Cancel" Variant="Variant.Filled" Color="Color.Error">Cancel</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[Parameter] public required List<IdentityRole> Roles { get; set; }
|
||||||
|
|
||||||
|
[CascadingParameter]
|
||||||
|
public IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
|
|
||||||
|
private string _newUsername = string.Empty;
|
||||||
|
private string _newUserRole = string.Empty;
|
||||||
|
|
||||||
|
private async Task CreateNewUser()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(_newUsername) || string.IsNullOrWhiteSpace(_newUserRole))
|
||||||
|
{
|
||||||
|
Snackbar.Add("Add Username and Role" , Severity.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationUser newUser = new ApplicationUser
|
||||||
|
{
|
||||||
|
UserName = _newUsername,
|
||||||
|
EmailConfirmed = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = await UserManager.CreateAsync(newUser, "NewPassword123!");
|
||||||
|
|
||||||
|
if(result.Succeeded)
|
||||||
|
{
|
||||||
|
await UserManager.AddToRoleAsync(newUser, _newUserRole);
|
||||||
|
MudDialog.Close(DialogResult.Ok(newUser));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Snackbar.Add("User could not be created", Severity.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Cancel()
|
||||||
|
{
|
||||||
|
MudDialog.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,15 @@
|
|||||||
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
@attribute [Authorize(Roles = "Admin")]
|
@attribute [Authorize(Roles = "Admin")]
|
||||||
|
|
||||||
<h3>Index</h3>
|
<h3>Index</h3>
|
||||||
|
|
||||||
|
<MudLink Href="AdminSettings/CouchLogSettings">CouchLog Settings</MudLink>
|
||||||
|
<MudLink Href="AdminSettings/UserManagement">User Management</MudLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,115 +1,51 @@
|
|||||||
@page "/AdminSettings/UserManagement"
|
@page "/AdminSettings/UserManagement"
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
@using CouchLog.Components.AdminSettings.Pages.Dialogs
|
||||||
@using CouchLog.Data
|
@using CouchLog.Data
|
||||||
@using Microsoft.AspNetCore.Identity
|
@using Microsoft.AspNetCore.Identity
|
||||||
@using Microsoft.EntityFrameworkCore
|
@using Microsoft.EntityFrameworkCore
|
||||||
@using Microsoft.AspNetCore.Components.QuickGrid
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
|
||||||
@inject ApplicationDbContext CouchLogDB
|
@inject ApplicationDbContext CouchLogDb
|
||||||
@inject UserManager<ApplicationUser> UserManager
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
@inject RoleManager<IdentityRole> RoleManager
|
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject IDialogService DialogService
|
||||||
|
@inject ISnackbar Snackbar
|
||||||
|
|
||||||
@attribute [Authorize(Roles = "Admin")]
|
@attribute [Authorize(Roles = "Admin")]
|
||||||
|
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<MudStack Row="true">
|
||||||
<h3 class="mb-0">UserManagement</h3>
|
<MudText Typo="Typo.h3">UserManagement</MudText>
|
||||||
|
<MudSpacer/>
|
||||||
|
<MudFab StartIcon="@Icons.Material.Filled.Add" Color="Color.Primary" OnClick="OpenCreateUserDialog"/>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
<button type="button"
|
<br/>
|
||||||
class="btn btn-primary"
|
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#exampleModal">
|
|
||||||
Add User
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<MudDataGrid Items="_gridUsers" Filterable="false" SortMode="@SortMode.Single" Groupable="false">
|
||||||
<QuickGrid Items="@gridUsers.AsQueryable()">
|
<Columns>
|
||||||
<PropertyColumn Title="#" Property="@(u => u.Index)" />
|
<PropertyColumn Property="arg => arg.Index " Title="Index"/>
|
||||||
<PropertyColumn Title="Username" Property="@(u => u.UserName)" />
|
<PropertyColumn Property="arg => arg.UserId" Title="User Id"/>
|
||||||
<PropertyColumn Title="Role" Property="@(u => u.Role)" />
|
<PropertyColumn Property="arg => arg.UserName" Title="User Name"/>
|
||||||
|
<PropertyColumn Property="arg => arg.Role" Title="Role"/>
|
||||||
<TemplateColumn Title="">
|
<TemplateColumn>
|
||||||
@if(context.UserId != currentUserId)
|
<CellTemplate>
|
||||||
|
@if (context.Item.UserId != _currentUserId)
|
||||||
{
|
{
|
||||||
<button class="btn btn-danger btn-sm" @onclick="() => DeleteUser(context)">Delete</button>
|
<MudFab Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="@(() => DeleteUser(context.Item))"/>
|
||||||
}
|
}
|
||||||
|
</CellTemplate>
|
||||||
</TemplateColumn>
|
</TemplateColumn>
|
||||||
</QuickGrid>
|
</Columns>
|
||||||
</div>
|
</MudDataGrid>
|
||||||
<!-- #region UserCreate Modal -->
|
|
||||||
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" style="color: black">
|
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" style="color: black" id="exampleModalLabel">Create User</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<!-- 1. Username Input mit Binding und Bootstrap Klasse -->
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="newUsernameInput" class="form-label">Username:</label>
|
|
||||||
<input type="text" class="form-control" id="newUsernameInput" @bind="newUsername" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 2. Select mit Binding -->
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Role:</label>
|
|
||||||
<select class="form-select" @bind="newUserRoleId">
|
|
||||||
<!-- WICHTIG: Eine leere Option als Standard, damit man weiß, ob etwas gewählt wurde -->
|
|
||||||
<option value="" selected disabled>Bitte Rolle wählen...</option>
|
|
||||||
|
|
||||||
@foreach (var role in roles)
|
|
||||||
{
|
|
||||||
<option value="@role.Id">@role.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</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" @onclick="CreateUserAsync">Create User</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- #endregion -->
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private string? _currentUserId;
|
||||||
string newUsername = "";
|
private List<ApplicationUser> _users = new();
|
||||||
string newUserRoleId = "";
|
private List<IdentityRole> _roles = new();
|
||||||
List<UserGridItem> gridUsers = new();
|
private List<UserGridItem> _gridUsers = new();
|
||||||
List<IdentityRole> roles = new();
|
|
||||||
string? currentUserId;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
|
||||||
currentUserId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
|
|
||||||
|
|
||||||
var users = await CouchLogDB.Users.ToListAsync();
|
|
||||||
roles = await CouchLogDB.Roles.ToListAsync();
|
|
||||||
int index = 1;
|
|
||||||
|
|
||||||
gridUsers.Clear();
|
|
||||||
|
|
||||||
foreach (var user in users)
|
|
||||||
{
|
|
||||||
var role = await UserManager.GetRolesAsync(user);
|
|
||||||
|
|
||||||
gridUsers.Add(new UserGridItem
|
|
||||||
{
|
|
||||||
Index = index++,
|
|
||||||
UserId = user.Id,
|
|
||||||
UserName = user.UserName!,
|
|
||||||
Role = role.FirstOrDefault() ?? "-"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UserGridItem
|
public class UserGridItem
|
||||||
{
|
{
|
||||||
@@ -119,9 +55,59 @@
|
|||||||
public string Role { get; set; } = "";
|
public string Role { get; set; } = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
|
_currentUserId = authState.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
|
||||||
|
|
||||||
|
var users = await CouchLogDb.Users.ToListAsync();
|
||||||
|
_roles = await CouchLogDb.Roles.ToListAsync();
|
||||||
|
|
||||||
|
await CreateGridUserObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CreateGridUserObjects()
|
||||||
|
{
|
||||||
|
_gridUsers.Clear();
|
||||||
|
|
||||||
|
var users = await CouchLogDb.Users.ToListAsync();
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
|
foreach (var user in users)
|
||||||
|
{
|
||||||
|
|
||||||
|
var role = await UserManager.GetRolesAsync(user);
|
||||||
|
|
||||||
|
_gridUsers.Add(new UserGridItem
|
||||||
|
{
|
||||||
|
Index = index++,
|
||||||
|
UserId = user.Id,
|
||||||
|
UserName = user.UserName!,
|
||||||
|
Role = role.FirstOrDefault() ?? "-"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OpenCreateUserDialog()
|
||||||
|
{
|
||||||
|
var parameters = new DialogParameters<CreateUserDialog>
|
||||||
|
{
|
||||||
|
{ x => x.Roles, _roles }
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialog = await DialogService.ShowAsync<CreateUserDialog>("Create User", parameters);
|
||||||
|
var result = await dialog.Result;
|
||||||
|
if (!result!.Canceled && result.Data is ApplicationUser newUser)
|
||||||
|
{
|
||||||
|
Snackbar.Add("User created", Severity.Success);
|
||||||
|
await CreateGridUserObjects();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async Task DeleteUser(UserGridItem user)
|
async Task DeleteUser(UserGridItem user)
|
||||||
{
|
{
|
||||||
if (user.UserId == currentUserId)
|
if (user.UserId == _currentUserId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var identityUser = await UserManager.FindByIdAsync(user.UserId);
|
var identityUser = await UserManager.FindByIdAsync(user.UserId);
|
||||||
@@ -133,48 +119,12 @@
|
|||||||
|
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
gridUsers.Remove(user);
|
_gridUsers.Remove(user);
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Optional: Fehler anzeigen
|
Snackbar.Add(result.Errors.ToString()!, Severity.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateUserAsync()
|
|
||||||
{
|
|
||||||
// Validierung
|
|
||||||
if (string.IsNullOrWhiteSpace(newUsername) || string.IsNullOrWhiteSpace(newUserRoleId))
|
|
||||||
{
|
|
||||||
// Fehlermeldung anzeigen oder abbrechen
|
|
||||||
Console.WriteLine("Bitte Benutzername und Rolle angeben.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hier deine Logik zum Erstellen des Users
|
|
||||||
var roleIdToUse = newUserRoleId;
|
|
||||||
var usernameToUse = newUsername;
|
|
||||||
|
|
||||||
ApplicationUser newUser = new ApplicationUser
|
|
||||||
{
|
|
||||||
UserName = newUsername,
|
|
||||||
EmailConfirmed = true
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = await UserManager.CreateAsync(newUser, "NewPassword123!");
|
|
||||||
|
|
||||||
IdentityRole roleName = roles.FirstOrDefault(r => r.Id == newUserRoleId);
|
|
||||||
|
|
||||||
if(result.Succeeded)
|
|
||||||
{
|
|
||||||
await UserManager.AddToRoleAsync(newUser, roleName.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modal schließen oder Formular zurücksetzen
|
|
||||||
newUsername = "";
|
|
||||||
newUserRoleId = "";
|
|
||||||
|
|
||||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,27 @@
|
|||||||
|
|
||||||
@attribute [Authorize(Roles = "Admin")]
|
@attribute [Authorize(Roles = "Admin")]
|
||||||
|
|
||||||
<h1>Manage CouchLog</h1>
|
<MudText Typo="Typo.h1">Manage CouchLog</MudText>
|
||||||
|
|
||||||
<div>
|
<MudContainer MaxWidth="MaxWidth.False" Class="pa-4">
|
||||||
<h2></h2>
|
<MudGrid>
|
||||||
<hr />
|
<MudItem xs="12" md="3" lg="2">
|
||||||
<div class="row">
|
<MudNavMenu>
|
||||||
<div class="col-lg-3">
|
<MudNavLink Href="/AdminSettings/CouchLogSettings"
|
||||||
<AdminSettingsNavMenu />
|
Icon="@Icons.Material.Filled.Settings">
|
||||||
</div>
|
CouchLog Settings
|
||||||
<div class="col-lg-9">
|
</MudNavLink>
|
||||||
|
|
||||||
|
<MudNavLink Href="/AdminSettings/UserManagement"
|
||||||
|
Match="NavLinkMatch.All"
|
||||||
|
Icon="@Icons.Material.Filled.People">
|
||||||
|
User Management
|
||||||
|
</MudNavLink>
|
||||||
|
</MudNavMenu>
|
||||||
|
</MudItem>
|
||||||
|
|
||||||
|
<MudItem xs="12" md="9" lg="10">
|
||||||
@Body
|
@Body
|
||||||
</div>
|
</MudItem>
|
||||||
</div>
|
</MudGrid>
|
||||||
</div>
|
</MudContainer>
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
@using Microsoft.AspNetCore.Identity
|
|
||||||
@using CouchLog.Data
|
|
||||||
|
|
||||||
@inject SignInManager<ApplicationUser> SignInManager
|
|
||||||
|
|
||||||
<ul class="nav nav-pills flex-column">
|
|
||||||
<li class="nav-item">
|
|
||||||
<NavLink class="nav-link" href="/AdminSettings/UserManagement" Match="NavLinkMatch.All">User Management</NavLink>
|
|
||||||
</li>
|
|
||||||
<!--
|
|
||||||
<li class="nav-item">
|
|
||||||
<NavLink class="nav-link" href=""></NavLink>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<NavLink class="nav-link" href=""></NavLink>
|
|
||||||
</li>
|
|
||||||
-->
|
|
||||||
</ul>
|
|
||||||
@@ -1,23 +1,32 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
|
|
||||||
<link rel="stylesheet" href="@Assets["app.css"]" />
|
|
||||||
<link rel="stylesheet" href="@Assets["CouchLog.styles.css"]" />
|
<link rel="stylesheet" href="@Assets["CouchLog.styles.css"]" />
|
||||||
<ImportMap />
|
<ImportMap />
|
||||||
<HeadOutlet />
|
|
||||||
|
@* Rendermode get's hand over dynamic *@
|
||||||
|
<HeadOutlet @rendermode="RenderModeForPage" />
|
||||||
|
|
||||||
|
<!-- #MudBlazor -->
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
|
||||||
|
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
|
||||||
|
<!-- #endregion -->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<Routes />
|
@* Rendermode get's hand over dynamic *@
|
||||||
|
<Routes @rendermode="RenderModeForPage" />
|
||||||
<script src="_framework/blazor.web.js"></script>
|
<script src="_framework/blazor.web.js"></script>
|
||||||
<script src="lib/bootstrap/dist/js/bootstrap.js"></script>
|
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
|
||||||
<script src="lib/bootstrap/dist/js/bootstrap.min.js"></script>
|
|
||||||
<script src="lib/bootstrap/dist/js/site.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[CascadingParameter]
|
||||||
|
private HttpContext HttpContext { get; set; } = default!;
|
||||||
|
|
||||||
|
private Microsoft.AspNetCore.Components.IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/Account") ? null : Microsoft.AspNetCore.Components.Web.RenderMode.InteractiveServer;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
@inherits LayoutComponentBase
|
||||||
|
@using MudBlazor
|
||||||
|
|
||||||
|
<MudThemeProvider IsDarkMode="true" />
|
||||||
|
<MudDialogProvider />
|
||||||
|
<MudSnackbarProvider />
|
||||||
|
|
||||||
|
<MudLayout>
|
||||||
|
<MudMainContent>
|
||||||
|
<MudContainer MaxWidth="MaxWidth.Large" Class="mt-8">
|
||||||
|
@Body
|
||||||
|
</MudContainer>
|
||||||
|
</MudMainContent>
|
||||||
|
</MudLayout>
|
||||||
@@ -1,19 +1,40 @@
|
|||||||
@inherits LayoutComponentBase
|
@inherits LayoutComponentBase
|
||||||
|
@using MudBlazor
|
||||||
|
|
||||||
<div class="page">
|
<MudThemeProvider @bind-IsDarkMode="@_isDarkMode" />
|
||||||
<div class="sidebar">
|
<MudDialogProvider />
|
||||||
|
<MudSnackbarProvider />
|
||||||
|
<MudPopoverProvider />
|
||||||
|
|
||||||
|
<MudLayout>
|
||||||
|
<MudAppBar Color="Color.Primary" Fixed="true">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
|
||||||
|
<MudText Typo="Typo.h6">CouchLog</MudText>
|
||||||
|
</MudAppBar>
|
||||||
|
|
||||||
|
<MudDrawer @bind-Open="@_drawerOpen" ClipMode="DrawerClipMode.Always" Elevation="1">
|
||||||
<NavMenu />
|
<NavMenu />
|
||||||
</div>
|
</MudDrawer>
|
||||||
|
|
||||||
<main>
|
<MudMainContent>
|
||||||
<article class="content px-4">
|
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
|
||||||
@Body
|
@Body
|
||||||
</article>
|
</MudContainer>
|
||||||
</main>
|
</MudMainContent>
|
||||||
|
</MudLayout>
|
||||||
|
|
||||||
|
<div id="blazor-error-ui">
|
||||||
|
An unhandled error has occurred.
|
||||||
|
<a href="" class="reload">Reload</a>
|
||||||
|
<a class="dismiss">🗙</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="blazor-error-ui" data-nosnippet>
|
@code {
|
||||||
An unhandled error has occurred.
|
bool _drawerOpen = true;
|
||||||
<a href="." class="reload">Reload</a>
|
bool _isDarkMode = true;
|
||||||
<span class="dismiss">🗙</span>
|
|
||||||
</div>
|
void DrawerToggle()
|
||||||
|
{
|
||||||
|
_drawerOpen = !_drawerOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
.page {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row {
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
border-bottom: 1px solid #d6d5d5;
|
|
||||||
justify-content: flex-end;
|
|
||||||
height: 3.5rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-left: 1.5rem;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a:first-child {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 640.98px) {
|
|
||||||
.top-row {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 641px) {
|
|
||||||
.page {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
width: 250px;
|
|
||||||
height: 100vh;
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row {
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row.auth ::deep a:first-child {
|
|
||||||
flex: 1;
|
|
||||||
text-align: right;
|
|
||||||
width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row, article {
|
|
||||||
padding-left: 2rem !important;
|
|
||||||
padding-right: 1.5rem !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#blazor-error-ui {
|
|
||||||
color-scheme: light only;
|
|
||||||
background: lightyellow;
|
|
||||||
bottom: 0;
|
|
||||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: none;
|
|
||||||
left: 0;
|
|
||||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#blazor-error-ui .dismiss {
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
right: 0.75rem;
|
|
||||||
top: 0.5rem;
|
|
||||||
}
|
|
||||||
@@ -5,81 +5,70 @@
|
|||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
@inject UserManager<ApplicationUser> UserManager
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
|
@inject ApplicationDbContext CouchLogDB
|
||||||
|
|
||||||
<div class="top-row ps-3 navbar navbar-dark">
|
<MudNavMenu>
|
||||||
<div class="container-fluid">
|
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">
|
||||||
<a class="navbar-brand" href="">CouchLog</a>
|
Home
|
||||||
</div>
|
</MudNavLink>
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
|
<MudNavLink Href="GlobalList" Icon="@Icons.Material.Filled.List">
|
||||||
|
Globallist
|
||||||
|
</MudNavLink>
|
||||||
|
|
||||||
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
|
<MudNavLink Href="PrivateList" Icon="@Icons.Material.Filled.Lock">
|
||||||
<nav class="nav flex-column">
|
Privatelist
|
||||||
<div class="nav-item px-3">
|
</MudNavLink>
|
||||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
|
||||||
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
<div class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="GlobalList">
|
|
||||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Global List
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
<div class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="PrivateList">
|
|
||||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Private List
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<AuthorizeView Roles="Admin">
|
<AuthorizeView Roles="Admin">
|
||||||
<div class="nav-item px-3">
|
<MudNavLink Href="AdminSettings" Icon="@Icons.Material.Filled.AdminPanelSettings">
|
||||||
<NavLink class="nav-link" href="AdminSettings">
|
Admin Settings
|
||||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Admin Settings
|
</MudNavLink>
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
</AuthorizeView>
|
</AuthorizeView>
|
||||||
|
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<Authorized>
|
<Authorized>
|
||||||
<div class="nav-item px-3">
|
<MudDivider Class="my-2" />
|
||||||
<NavLink class="nav-link" href="Account/Manage">
|
<MudNavLink Href="Account/Manage" Icon="@Icons.Material.Filled.Person">
|
||||||
<span class="bi bi-person-fill-nav-menu" aria-hidden="true"></span> @context.User.Identity?.Name
|
@context.User.Identity?.Name
|
||||||
</NavLink>
|
</MudNavLink>
|
||||||
</div>
|
|
||||||
<div class="nav-item px-3">
|
|
||||||
<form action="Account/Logout" method="post">
|
<form action="Account/Logout" method="post">
|
||||||
<AntiforgeryToken />
|
<AntiforgeryToken />
|
||||||
<input type="hidden" name="ReturnUrl" value="@currentUrl" />
|
<input type="hidden" name="ReturnUrl" value="@currentUrl" />
|
||||||
<button type="submit" class="nav-link">
|
<MudNavLink Icon="@Icons.Material.Filled.Logout"
|
||||||
<span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true"></span> Logout
|
OnClick="@(() => { })"
|
||||||
</button>
|
Href="javascript:void(0)"
|
||||||
|
UserAttributes="@(new Dictionary<string, object>
|
||||||
|
{ {"onclick", "this.closest('form').submit()"} })">
|
||||||
|
Logout
|
||||||
|
</MudNavLink>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</Authorized>
|
</Authorized>
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
<div class="nav-item px-3">
|
<MudDivider Class="my-2" />
|
||||||
<NavLink class="nav-link" href="Account/Register">
|
@if (_isRegistrationAllowed)
|
||||||
<span class="bi bi-person-nav-menu" aria-hidden="true"></span> Register
|
{
|
||||||
</NavLink>
|
<MudNavLink Href="Account/Register" Icon="@Icons.Material.Filled.PersonAdd">
|
||||||
</div>
|
Register
|
||||||
<div class="nav-item px-3">
|
</MudNavLink>
|
||||||
<NavLink class="nav-link" href="Account/Login">
|
}
|
||||||
<span class="bi bi-person-badge-nav-menu" aria-hidden="true"></span> Login
|
<MudNavLink Href="Account/Login" Icon="@Icons.Material.Filled.Badge">
|
||||||
</NavLink>
|
Login
|
||||||
</div>
|
</MudNavLink>
|
||||||
</NotAuthorized>
|
</NotAuthorized>
|
||||||
</AuthorizeView>
|
</AuthorizeView>
|
||||||
</nav>
|
|
||||||
</div>
|
</MudNavMenu>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string? currentUrl;
|
private string? currentUrl;
|
||||||
|
private bool _isRegistrationAllowed;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
currentUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
|
currentUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
|
||||||
NavigationManager.LocationChanged += OnLocationChanged;
|
NavigationManager.LocationChanged += OnLocationChanged;
|
||||||
|
_isRegistrationAllowed = CouchLogDB.AccountsSettings.First().IsRegistrationAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLocationChanged(object? sender, LocationChangedEventArgs e)
|
private void OnLocationChanged(object? sender, LocationChangedEventArgs e)
|
||||||
@@ -93,4 +82,3 @@
|
|||||||
NavigationManager.LocationChanged -= OnLocationChanged;
|
NavigationManager.LocationChanged -= OnLocationChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
.navbar-toggler {
|
|
||||||
appearance: none;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 3.5rem;
|
|
||||||
height: 2.5rem;
|
|
||||||
color: white;
|
|
||||||
position: absolute;
|
|
||||||
top: 0.5rem;
|
|
||||||
right: 1rem;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-toggler:checked {
|
|
||||||
background-color: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-row {
|
|
||||||
min-height: 3.5rem;
|
|
||||||
background-color: rgba(0,0,0,0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-brand {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
width: 1.25rem;
|
|
||||||
height: 1.25rem;
|
|
||||||
margin-right: 0.75rem;
|
|
||||||
top: -1px;
|
|
||||||
background-size: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-house-door-fill-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-plus-square-fill-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-list-nested-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-lock-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath d='M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2zM5 8h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-person-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person' viewBox='0 0 16 16'%3E%3Cpath d='M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-person-badge-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person-badge' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3zM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z'/%3E%3Cpath d='M4.5 0A2.5 2.5 0 0 0 2 2.5V14a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2.5A2.5 2.5 0 0 0 11.5 0h-7zM3 2.5A1.5 1.5 0 0 1 4.5 1h7A1.5 1.5 0 0 1 13 2.5v10.795a4.2 4.2 0 0 0-.776-.492C11.392 12.387 10.063 12 8 12s-3.392.387-4.224.803a4.2 4.2 0 0 0-.776.492V2.5z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-person-fill-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person-fill' viewBox='0 0 16 16'%3E%3Cpath d='M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3Zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.bi-arrow-bar-left-nav-menu {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-arrow-bar-left' viewBox='0 0 16 16'%3E%3Cpath d='M12.5 15a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5ZM10 8a.5.5 0 0 1-.5.5H3.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L3.707 7.5H9.5a.5.5 0 0 1 .5.5Z'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item:first-of-type {
|
|
||||||
padding-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item:last-of-type {
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item ::deep .nav-link {
|
|
||||||
color: #d7d7d7;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
height: 3rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
line-height: 3rem;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item ::deep a.active {
|
|
||||||
background-color: rgba(255,255,255,0.37);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item ::deep .nav-link:hover {
|
|
||||||
background-color: rgba(255,255,255,0.1);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-scrollable {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-toggler:checked ~ .nav-scrollable {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 641px) {
|
|
||||||
.navbar-toggler {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-scrollable {
|
|
||||||
/* Never collapse the sidebar for wide screens */
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
/* Allow sidebar to scroll for tall menus */
|
|
||||||
height: calc(100vh - 3.5rem);
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,322 +0,0 @@
|
|||||||
@page "/GlobalList"
|
|
||||||
@rendermode InteractiveServer
|
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
|
||||||
@using CouchLog.Data
|
|
||||||
@using Microsoft.AspNetCore.Identity
|
|
||||||
@using Microsoft.EntityFrameworkCore
|
|
||||||
|
|
||||||
@inject ApplicationDbContext CouchLogDB
|
|
||||||
@inject UserManager<ApplicationUser> UserManager
|
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
|
|
||||||
@attribute [Authorize]
|
|
||||||
|
|
||||||
<PageTitle>GlobalList</PageTitle>
|
|
||||||
|
|
||||||
<div class="container-fluid mt-4">
|
|
||||||
<!-- #region CreateEntity -->
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
||||||
<h2>Global List</h2>
|
|
||||||
<button class="btn btn-info" type="button" @onclick="ToogleCollapseNewGlobalEntity">@(isCollapseNewGlobalEntityOpen ? "X" : "Add Entity")</button>
|
|
||||||
</div>
|
|
||||||
<div class="collapse @(isCollapseNewGlobalEntityOpen ? "show" : "")" id="CollapseCreateNewGlobalEntity">
|
|
||||||
<div class="mb-4 align-items-center CreateNewGlobalEntity-Container">
|
|
||||||
<EditForm Model="@GlobalEntity" OnSubmit="CreateNewGlobalEntity" FormName="CreateNewGlobalEntityForm">
|
|
||||||
<DataAnnotationsValidator />
|
|
||||||
<ValidationSummary />
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="Title" class="form-label">Title</label>
|
|
||||||
<InputText id="Title" class="form-control" @bind-Value="GlobalEntity.Title"></InputText>
|
|
||||||
<ValidationMessage For="@(() => GlobalEntity.Title)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="Type" class="form-label">Type</label>
|
|
||||||
<select id="Type" class="form-select" @bind="SelectedMediaTypeId">
|
|
||||||
@foreach(MediaType Type in MediaTypes)
|
|
||||||
{
|
|
||||||
<option value="@Type.Id">@Type.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<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>
|
|
||||||
<div class="mb-3">
|
|
||||||
<InputCheckbox DisplayName="isPrivate" @bind-Value="isPrivate" ></InputCheckbox>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn-success btn">Create new Global Entity</button>
|
|
||||||
</EditForm>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- #endregion -->
|
|
||||||
|
|
||||||
<!-- #region Show Entitys -->
|
|
||||||
<div class="row">
|
|
||||||
@foreach (var Entity in GlobalEntities)
|
|
||||||
{
|
|
||||||
if (!Entity.IsPrivate || (Entity.IsPrivate && (Entity.CreatorId == AppUser.Id)))
|
|
||||||
{
|
|
||||||
<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 class="Entity-Container-Menu-Button dropdown ms-1">
|
|
||||||
<button type="button" class="Entity-Container-Menu-Button btn menu-btn" data-bs-toggle="modal" data-bs-target="#modal-@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="">
|
|
||||||
<a href="javascript:void(0)" class="Entity-Container-Image">
|
|
||||||
<img src="/@Entity.PicturePath" alt="" class="Entity-Container-Image" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div name="Entity-Container-Data" class="">
|
|
||||||
<h3 class="">@Entity.Title</h3>
|
|
||||||
</div>
|
|
||||||
<div name="Entity-Container-Button" class="d-flex Entity-Container-Button" style="gap: 10px;">
|
|
||||||
<button class="btn btn-info" type="button" @onclick="() => AddToPrivateList(Entity)">
|
|
||||||
@(IsInPrivateList(Entity.Id) ? "Added" : "Add to Private List")
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-info" type="button" @onclick="() => throw new NotImplementedException()">Add to Shared List</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" id="modal-@Entity.Id" tabindex="-1" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">Optionen</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<button class="btn btn-danger" type="button" @onclick="() => DeleteEntity(Entity)">Delete Entity</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<!-- #endregion -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code
|
|
||||||
{
|
|
||||||
private List<MediaType> MediaTypes = new List<MediaType>();
|
|
||||||
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 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;
|
|
||||||
private bool isPrivate = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="NotImplementedException"></exception>
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
GlobalEntities = await CouchLogDB.GlobalEntities.OrderByDescending(Entity => Entity.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();
|
|
||||||
User = AuthState.User;
|
|
||||||
|
|
||||||
AppUser = await UserManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
if (AppUser == null)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
var TempUserPrivateEntityIds = await CouchLogDB.PrivateEntities
|
|
||||||
.Where(p => p.UserId == AppUser.Id)
|
|
||||||
.Select(p => p.GlobalEntityId)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
//string Base64 = Convert.ToBase64String(Buffer);
|
|
||||||
//ImagePreviewUrl = $"data:{Picture.ContentType};base64,{Base64}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
private void ToogleCollapseNewGlobalEntity()
|
|
||||||
{
|
|
||||||
isCollapseNewGlobalEntityOpen = !isCollapseNewGlobalEntityOpen;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <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;
|
|
||||||
GlobalEntity.IsPrivate = isPrivate;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return UserPrivateEntityIds.Contains(GolbalEntityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="GlobalEntity"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task AddToPrivateList(GlobalEntity GlobalEntity)
|
|
||||||
{
|
|
||||||
if(User.Identity?.IsAuthenticated == true)
|
|
||||||
{
|
|
||||||
if(!IsInPrivateList(GlobalEntity.Id))
|
|
||||||
{
|
|
||||||
if (AppUser is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("User not loaded or not logged in.");
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivateEntity PrivateEntity = new()
|
|
||||||
{
|
|
||||||
UserId = AppUser.Id,
|
|
||||||
CreationTime = DateTime.Now,
|
|
||||||
GlobalEntityId = GlobalEntity.Id,
|
|
||||||
UserWatchStatusId = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
CouchLogDB.PrivateEntities.Add(PrivateEntity);
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
|
|
||||||
UserPrivateEntityIds.Add(GlobalEntity.Id);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddGenreToList(int GenreId)
|
|
||||||
{
|
|
||||||
if (!GenreIds.Contains(GenreId))
|
|
||||||
{
|
|
||||||
GenreIds.Add(GenreId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteEntity(GlobalEntity entity)
|
|
||||||
{
|
|
||||||
if(entity.PicturePath != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(Path.Combine("wwwroot", entity.PicturePath));
|
|
||||||
}
|
|
||||||
catch(Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CouchLogDB.GlobalEntities.Remove(entity);
|
|
||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
|
|
||||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/*For Development*/
|
|
||||||
/** {
|
|
||||||
outline: 1px solid red !important;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
.Entity-Container {
|
|
||||||
color:aliceblue
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container:hover {
|
|
||||||
color: rgba(0,255,255,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card {
|
|
||||||
position: relative;
|
|
||||||
max-width: 275px;
|
|
||||||
background: #111;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 15px;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
text-align: center;
|
|
||||||
gap: 0.75rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.Entity-Container-Card h2 {
|
|
||||||
color: #0ff;
|
|
||||||
font-size: 2rem;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: -50%;
|
|
||||||
left: -50%;
|
|
||||||
width: 200%;
|
|
||||||
height: 200%;
|
|
||||||
background: linear-gradient( 0deg, transparent, transparent 30%, rgba(0,255,255,0.3) );
|
|
||||||
transform: rotate(-45deg);
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
box-shadow: 0 0 20px rgba(0,255,255,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card:hover::before {
|
|
||||||
opacity: 1;
|
|
||||||
transform: rotate(-45deg) translateY(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Image {
|
|
||||||
margin: 4px;
|
|
||||||
margin-top: 6px;
|
|
||||||
max-width: 256px;
|
|
||||||
max-height: 256px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Button {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column
|
|
||||||
}
|
|
||||||
|
|
||||||
.CreateNewGlobalEntity-Container {
|
|
||||||
background: #111;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
@using CouchLog.Data
|
||||||
|
|
||||||
|
<MudCard>
|
||||||
|
<MudPaper Elevation="0">
|
||||||
|
<MudCardMedia Image="@GlobalEntity.PicturePath" Height="400" Style="object-fit: contain;"/>
|
||||||
|
</MudPaper>
|
||||||
|
<MudCardContent>
|
||||||
|
<MudText Typo="Typo.h5">@GlobalEntity.Title</MudText>
|
||||||
|
</MudCardContent>
|
||||||
|
<MudCardActions>
|
||||||
|
<MudTooltip Text="Add to shared List">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Rounded.People" Color="Color.Primary" OnClick="@(() => OnAddToShared.InvokeAsync(GlobalEntity))" />
|
||||||
|
</MudTooltip>
|
||||||
|
<MudSpacer/>
|
||||||
|
@if (UserPrivateEntityIds.Contains(GlobalEntity.Id))
|
||||||
|
{
|
||||||
|
<MudTooltip Text="Already added to Private List">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Rounded.Check" Color="Color.Primary"/>
|
||||||
|
</MudTooltip>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudTooltip Text="Add to private List">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Rounded.Lock" Color="Color.Primary" OnClick="@(() => OnAddToPrivate.InvokeAsync(GlobalEntity))" />
|
||||||
|
</MudTooltip>
|
||||||
|
}
|
||||||
|
</MudCardActions>
|
||||||
|
</MudCard>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[Parameter] public GlobalEntity GlobalEntity { get; set; } = null!;
|
||||||
|
[Parameter] public HashSet<int> UserPrivateEntityIds { get; set; } = null!;
|
||||||
|
|
||||||
|
[Parameter] public EventCallback<GlobalEntity> OnAddToPrivate { get; set; }
|
||||||
|
[Parameter] public EventCallback<GlobalEntity> OnAddToShared { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using System.ComponentModel.DataAnnotations
|
||||||
|
|
||||||
|
@inject ApplicationDbContext CouchLogDB
|
||||||
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject ISnackbar Snackbar
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.mud-file-upload-dragarea {
|
||||||
|
height: 400px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<TitleContent>
|
||||||
|
<MudText Typo="Typo.h6">Add Global Entity</MudText>
|
||||||
|
</TitleContent>
|
||||||
|
|
||||||
|
<DialogContent>
|
||||||
|
<EditForm EditContext="_editContext" OnSubmit="HandleSubmit">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
|
||||||
|
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Start" Style="min-height: 400px;">
|
||||||
|
<!--<editor-fold desc="Picture-Upload">-->
|
||||||
|
<MudPaper Class="pa-0" Elevation="0" Width="280px" MinWidth="280px">
|
||||||
|
@if (!string.IsNullOrWhiteSpace(_imagePreview))
|
||||||
|
{
|
||||||
|
<MudImage Src="@_imagePreview"
|
||||||
|
ObjectFit="ObjectFit.Contain"
|
||||||
|
Class="rounded"
|
||||||
|
Style="width: 280px; height: 400px;"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudFileUpload @bind-Files="_pictureFile"
|
||||||
|
DragAndDrop="true"
|
||||||
|
OnFilesChanged="OnPictureUploaded"
|
||||||
|
Accept="image/*"
|
||||||
|
InputClass="null"
|
||||||
|
Class="mud-file-upload-dragarea">
|
||||||
|
<SelectedTemplate Context="SelectedTemplateContext"/>
|
||||||
|
</MudFileUpload>
|
||||||
|
}
|
||||||
|
</MudPaper>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
|
||||||
|
<MudPaper Class="flex-grow-1" Elevation="0">
|
||||||
|
<MudStack Spacing="3">
|
||||||
|
|
||||||
|
<MudTextField @bind-Value="_form.Title"
|
||||||
|
Label="Title"
|
||||||
|
For="@(() => _form.Title)"
|
||||||
|
Variant="Variant.Outlined" />
|
||||||
|
|
||||||
|
<MudSelect T="int"
|
||||||
|
@bind-Value="_selectedMediaTypeId"
|
||||||
|
Label="Type"
|
||||||
|
Variant="Variant.Outlined">
|
||||||
|
@foreach (var type in _mediaTypes)
|
||||||
|
{
|
||||||
|
<MudSelectItem T="int" Value="@type.Id">@type.Name</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
|
||||||
|
<MudSelect T="int"
|
||||||
|
Label="Genres"
|
||||||
|
MultiSelection="true"
|
||||||
|
@bind-SelectedValues="_selectedGenreIds"
|
||||||
|
Variant="Variant.Outlined">
|
||||||
|
@foreach (var genre in _genres)
|
||||||
|
{
|
||||||
|
<MudSelectItem T="int" Value="@genre.Id">@genre.Name</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
<MudCheckBox @bind-Value="_isPrivate" Label="Is Private" Color="Color.Primary" />
|
||||||
|
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Success" Disabled="_isSaving" Class="mt-3">
|
||||||
|
@if (_isSaving)
|
||||||
|
{
|
||||||
|
<MudProgressCircular Indeterminate="true" Size="Size.Small" Class="mr-2" />
|
||||||
|
<span>Saving...</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span>Create Global Entity</span>
|
||||||
|
}
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
</MudPaper>
|
||||||
|
</MudStack>
|
||||||
|
</EditForm>
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="Cancel" Variant="Variant.Text" Disabled="_isSaving">Cancel</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[CascadingParameter]
|
||||||
|
private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
|
|
||||||
|
private ApplicationUser? _appUser;
|
||||||
|
private EditContext _editContext = null!;
|
||||||
|
|
||||||
|
private List<MediaType> _mediaTypes = new();
|
||||||
|
private List<Genre> _genres = new();
|
||||||
|
|
||||||
|
private GlobalEntityFormModel _form = new();
|
||||||
|
private string? _imagePreview;
|
||||||
|
private int _selectedMediaTypeId;
|
||||||
|
private bool _isPrivate;
|
||||||
|
private bool _isSaving;
|
||||||
|
private IReadOnlyCollection<int> _selectedGenreIds = Array.Empty<int>();
|
||||||
|
|
||||||
|
//Picture
|
||||||
|
private IBrowserFile? _pictureFile;
|
||||||
|
|
||||||
|
private class GlobalEntityFormModel
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "Title is required.")]
|
||||||
|
[MaxLength(200, ErrorMessage = "Title may not exceed 200 characters.")]
|
||||||
|
public string Title { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
_editContext = new EditContext(_form);
|
||||||
|
|
||||||
|
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
|
_appUser = await UserManager.GetUserAsync(authState.User);
|
||||||
|
|
||||||
|
if (_appUser is null)
|
||||||
|
{
|
||||||
|
Snackbar.Add("Not authenticated.", Severity.Error);
|
||||||
|
MudDialog.Cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mediaTypes = await CouchLogDB.MediaType.OrderBy(t => t.Id).ToListAsync();
|
||||||
|
_genres = await CouchLogDB.Genres.OrderBy(t => t.Id).ToListAsync();
|
||||||
|
|
||||||
|
if (_mediaTypes.Count > 0)
|
||||||
|
_selectedMediaTypeId = _mediaTypes.First().Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnPictureUploaded()
|
||||||
|
{
|
||||||
|
if (_pictureFile == null)
|
||||||
|
{
|
||||||
|
Snackbar.Add("No file selected!", Severity.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_pictureFile.Size > 5242880)
|
||||||
|
{
|
||||||
|
Snackbar.Add("File size exceeds 5MB!", Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await using var stream = _pictureFile.OpenReadStream(5242880);
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
await stream.CopyToAsync(ms);
|
||||||
|
|
||||||
|
var base64 = Convert.ToBase64String(ms.ToArray());
|
||||||
|
_imagePreview = $"data:{_pictureFile.ContentType};base64,{base64}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel() => MudDialog.Cancel();
|
||||||
|
|
||||||
|
private async Task HandleSubmit(EditContext ctx)
|
||||||
|
{
|
||||||
|
if (!ctx.Validate()) return;
|
||||||
|
|
||||||
|
if (_pictureFile is null)
|
||||||
|
{
|
||||||
|
Snackbar.Add("Please upload a picture.", Severity.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_selectedMediaTypeId == 0)
|
||||||
|
{
|
||||||
|
Snackbar.Add("Please select a media type.", Severity.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isSaving = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string fileName = $"{Guid.NewGuid()}{Path.GetExtension(_pictureFile.Name)}";
|
||||||
|
string picturePath = Path.Combine("wwwroot", "Pictures", fileName);
|
||||||
|
|
||||||
|
await using (var fs = File.Create(picturePath))
|
||||||
|
{
|
||||||
|
await _pictureFile.OpenReadStream(maxAllowedSize: 10_000_000).CopyToAsync(fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
var entity = new GlobalEntity
|
||||||
|
{
|
||||||
|
Title = _form.Title,
|
||||||
|
PicturePath = $"Pictures/{fileName}",
|
||||||
|
CreatorId = _appUser!.Id,
|
||||||
|
TypeId = _selectedMediaTypeId,
|
||||||
|
CreationTime = DateTime.UtcNow,
|
||||||
|
IsPrivate = _isPrivate
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchLogDB.Add(entity);
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
|
||||||
|
foreach (int genreId in _selectedGenreIds)
|
||||||
|
{
|
||||||
|
CouchLogDB.Add(new LinkTableGlobalGenre
|
||||||
|
{
|
||||||
|
GenreId = genreId,
|
||||||
|
GlobalEntityId = entity.Id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
|
||||||
|
Snackbar.Add("Global Entity created!", Severity.Success);
|
||||||
|
MudDialog.Close(DialogResult.Ok(entity));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Snackbar.Add($"Error: {ex.Message}", Severity.Error);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isSaving = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
@page "/GlobalList"
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
@using CouchLog.Components.Pages.GlobalList.Dialogs
|
||||||
|
@using CouchLog.Components.Pages.GlobalList.Components
|
||||||
|
|
||||||
|
@inject ApplicationDbContext CouchLogDb
|
||||||
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
|
@inject IDialogService DialogService
|
||||||
|
@inject ISnackbar Snackbar
|
||||||
|
|
||||||
|
@attribute [Authorize]
|
||||||
|
|
||||||
|
<PageTitle>GlobalList</PageTitle>
|
||||||
|
|
||||||
|
<MudContainer MaxWidth="MaxWidth.False">
|
||||||
|
@*Top of the Page*@
|
||||||
|
<MudContainer>
|
||||||
|
<MudStack Row="true" AlignItems="AlignItems.Center">
|
||||||
|
@*Page Title*@
|
||||||
|
<MudText Typo="Typo.h3" Style="font-weight: bold;">Global List</MudText>
|
||||||
|
|
||||||
|
@*Spacer*@
|
||||||
|
<MudSpacer />
|
||||||
|
|
||||||
|
@*Button for adding GlobalEntity*@
|
||||||
|
<MudTooltip Text="Add GlobalEntity">
|
||||||
|
<MudFab StartIcon="@Icons.Material.Filled.Add" Color="Color.Primary" OnClick="OpenAddNewGlobalEntityDialog"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</MudStack>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<MudContainer>
|
||||||
|
<MudPaper Class="pa-2" Elevation="1">
|
||||||
|
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
||||||
|
@*Search bar*@
|
||||||
|
<MudTextField @bind-Value="_searchString"
|
||||||
|
Placeholder="Search..."
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Search"
|
||||||
|
Immediate="true"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Margin="Margin.Dense"
|
||||||
|
Style="max-width: 300px;"/>
|
||||||
|
@*Refresh button*@
|
||||||
|
@*<MudTooltip Text="Refresh Entities">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="RefreshPage"/>
|
||||||
|
</MudTooltip>*@
|
||||||
|
@*More Filters button*@
|
||||||
|
<MudTooltip Text="More filters">
|
||||||
|
<MudIconButton Icon="@(_showFilters
|
||||||
|
? Icons.Material.Filled.ExpandLess
|
||||||
|
: Icons.Material.Filled.FilterList)"
|
||||||
|
OnClick="@(() => _showFilters = !_showFilters)"
|
||||||
|
Color="Color.Default"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</MudStack>
|
||||||
|
<MudCollapse Expanded="_showFilters">
|
||||||
|
@*Entity allready added*@
|
||||||
|
<MudSwitch @bind-Value="_showAlreadyAddedEntities" Color="Color.Primary">
|
||||||
|
Show already added Entities
|
||||||
|
</MudSwitch>
|
||||||
|
@*To be exstendet*@
|
||||||
|
</MudCollapse>
|
||||||
|
</MudPaper>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<MudContainer MaxWidth="MaxWidth.False">
|
||||||
|
<MudGrid Spacing="6" Justify="Justify.Center">
|
||||||
|
@foreach (var globalEntity in VisibleGlobalEntities)
|
||||||
|
{
|
||||||
|
<MudItem xs="12" sm="6" md="4" lg="3" xl="2">
|
||||||
|
<GlobalEntityCard GlobalEntity="globalEntity"
|
||||||
|
UserPrivateEntityIds="_userPrivateEntityIds"
|
||||||
|
OnAddToPrivate="AddGlobalEntityToPrivateList"
|
||||||
|
OnAddToShared="AddGlobalEntityToSharedList"/>
|
||||||
|
</MudItem>
|
||||||
|
}
|
||||||
|
</MudGrid>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<MudContainer>
|
||||||
|
<MudStack AlignItems="AlignItems.Center">
|
||||||
|
<MudPagination Count="@TotalPages" @bind-Selected="_currentPage"/>
|
||||||
|
</MudStack>
|
||||||
|
</MudContainer>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
//Filter
|
||||||
|
private string? _searchString;
|
||||||
|
private bool _showFilters;
|
||||||
|
private bool _showAlreadyAddedEntities = false;
|
||||||
|
private IEnumerable<GlobalEntity> FiltertGlobalEntities => _globalEntities.Where(entity =>
|
||||||
|
(string.IsNullOrWhiteSpace(_searchString) || entity.Title.Contains(_searchString, StringComparison.OrdinalIgnoreCase)) && //Search bar
|
||||||
|
(_showAlreadyAddedEntities || !_userPrivateEntityIds.Contains(entity.Id)) //Filter for already added Entitys
|
||||||
|
);
|
||||||
|
|
||||||
|
//Paging
|
||||||
|
private int _currentPage = 1;
|
||||||
|
private int _pageSize = 12;
|
||||||
|
private int TotalPages => (int)Math.Ceiling(FiltertGlobalEntities.Count() / (double)_pageSize);
|
||||||
|
private IEnumerable<GlobalEntity> VisibleGlobalEntities => FiltertGlobalEntities.Skip((_currentPage - 1) * _pageSize).Take(_pageSize);
|
||||||
|
|
||||||
|
//User
|
||||||
|
private ApplicationUser? _appUser;
|
||||||
|
|
||||||
|
//Core
|
||||||
|
private List<GlobalEntity> _globalEntities = [];
|
||||||
|
private HashSet<int> _userPrivateEntityIds = [];
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
|
_appUser = await UserManager.GetUserAsync(authState.User);
|
||||||
|
|
||||||
|
if (_appUser is null)
|
||||||
|
{
|
||||||
|
Snackbar.Add("Not authenticated.", Severity.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_globalEntities = await CouchLogDb.GlobalEntities
|
||||||
|
.OrderByDescending(entity => entity.CreationTime)
|
||||||
|
.Where(entity => !entity.IsPrivate || (entity.IsPrivate && entity.CreatorId == _appUser.Id))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
_userPrivateEntityIds = await CouchLogDb.PrivateEntities
|
||||||
|
.Where(entity => entity.UserId == _appUser.Id)
|
||||||
|
.Select(p => p.GlobalEntityId)
|
||||||
|
.ToHashSetAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task RefreshPage()
|
||||||
|
{
|
||||||
|
_currentPage = 1;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnNewEntity(GlobalEntity entity)
|
||||||
|
{
|
||||||
|
_globalEntities.Add(entity);
|
||||||
|
await RefreshPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OpenAddNewGlobalEntityDialog()
|
||||||
|
{
|
||||||
|
var dialog = await DialogService.ShowAsync<AddNewGlobalEntityDialog>("Add new Global Entity");
|
||||||
|
var result = await dialog.Result;
|
||||||
|
if (!result!.Canceled)
|
||||||
|
{
|
||||||
|
var entity = (GlobalEntity)result.Data!;
|
||||||
|
await OnNewEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddGlobalEntityToPrivateList(GlobalEntity globalEntity)
|
||||||
|
{
|
||||||
|
if(_appUser is null) { Snackbar.Add("Not logged in!", Severity.Error); return;}
|
||||||
|
|
||||||
|
if (!await IsInPrivateList(globalEntity.Id))
|
||||||
|
{
|
||||||
|
PrivateEntity privateEntity = new()
|
||||||
|
{
|
||||||
|
UserId = _appUser.Id,
|
||||||
|
CreationTime = DateTime.Now,
|
||||||
|
GlobalEntityId = globalEntity.Id,
|
||||||
|
UserWatchStatusId = 1,
|
||||||
|
//Season = 0,
|
||||||
|
//Episode = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchLogDb.PrivateEntities.Add(privateEntity);
|
||||||
|
await CouchLogDb.SaveChangesAsync();
|
||||||
|
|
||||||
|
_userPrivateEntityIds.Add(globalEntity.Id);
|
||||||
|
StateHasChanged();
|
||||||
|
Snackbar.Add("Added Entity to private List", Severity.Success);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Snackbar.Add("Entity already in private List!", Severity.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> IsInPrivateList(int globalEntityId)
|
||||||
|
{
|
||||||
|
if (_appUser is null) return false;
|
||||||
|
|
||||||
|
return await CouchLogDb.PrivateEntities.Where(entity => entity.UserId == _appUser.Id).AnyAsync(entity => entity.GlobalEntityId == globalEntityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddGlobalEntityToSharedList()
|
||||||
|
{
|
||||||
|
Snackbar.Add("Feature not implemented yet!", Severity.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
|
|
||||||
|
@using CouchLog.Components.Layout
|
||||||
@using Microsoft.AspNetCore.Authorization
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
|
|||||||
@@ -1,216 +0,0 @@
|
|||||||
@page "/PrivateList"
|
|
||||||
@rendermode InteractiveServer
|
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
|
||||||
@using CouchLog.Data
|
|
||||||
@using Microsoft.AspNetCore.Identity
|
|
||||||
@using Microsoft.EntityFrameworkCore
|
|
||||||
|
|
||||||
@inject ApplicationDbContext CouchLogDB
|
|
||||||
@inject UserManager<ApplicationUser> UserManager
|
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
|
|
||||||
@attribute [Authorize]
|
|
||||||
|
|
||||||
<PageTitle>Private List</PageTitle>
|
|
||||||
|
|
||||||
<div class="container-fluid mt-4 px-4">
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
||||||
<h2>Private List</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Grid-Layout -->
|
|
||||||
<div class="row g-4">
|
|
||||||
@foreach (var Entity in PrivateEntities)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Hier bleiben wir bei col-lg-6 (halbe Bildschirmbreite),
|
|
||||||
wie du es im roten Kasten wolltest.
|
|
||||||
*/
|
|
||||||
<div class="col-12 col-lg-6 col-xxl-4">
|
|
||||||
|
|
||||||
<div class="card shadow-sm border-0 overflow-hidden private-entity-card">
|
|
||||||
<div class="row g-0 h-100">
|
|
||||||
|
|
||||||
<!-- BILD: col-auto sorgt dafür, dass sich die Breite nach CSS richtet -->
|
|
||||||
<div class="col-auto img-wrapper">
|
|
||||||
@if (!string.IsNullOrEmpty(Entity.GlobalEntity?.PicturePath))
|
|
||||||
{
|
|
||||||
<img src="/@Entity.GlobalEntity.PicturePath"
|
|
||||||
class="entity-img"
|
|
||||||
alt="@Entity.GlobalEntity.Title">
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div class="d-flex align-items-center justify-content-center h-100 bg-light text-muted small px-2">
|
|
||||||
Kein Bild
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- INFO: 'col' nimmt automatisch den RESTLICHEN Platz ein -->
|
|
||||||
<div class="col">
|
|
||||||
<div class="card-body d-flex flex-column h-100 py-2 px-3">
|
|
||||||
|
|
||||||
<!-- Header -->
|
|
||||||
<div class="d-flex justify-content-between align-items-start">
|
|
||||||
<div class="overflow-hidden">
|
|
||||||
<h5 class="card-title fw-bold mb-0 text-truncate">@Entity.GlobalEntity?.Title</h5>
|
|
||||||
<small class="text-muted meta-text">
|
|
||||||
@Entity.CreationTime.ToShortDateString()
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dropdown ms-1">
|
|
||||||
<button class="btn btn-link menu-btn" type="button" data-bs-toggle="modal" data-bs-target="#modal-@Entity.Id">
|
|
||||||
⋮
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<select class="form-select"
|
|
||||||
value="@Entity.UserWatchStatusId"
|
|
||||||
@onchange="@(e => UpdateWatchStatus(Entity, e.Value))">
|
|
||||||
|
|
||||||
@foreach (var status in userWatchStatuses)
|
|
||||||
{
|
|
||||||
<option value="@status.Id">@status.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
|
|
||||||
@if (Entity.GlobalEntity?.MediaType.Name == "Series")
|
|
||||||
{
|
|
||||||
<select class="form-select" value="@Entity.Season" @onchange="@(e => UpdateSeason(Entity, e.Value))">
|
|
||||||
@{
|
|
||||||
int currentSeason = Entity.Season ?? 1;
|
|
||||||
|
|
||||||
int startOffsetSeason = currentSeason > 1 ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@for (int i = startOffsetSeason; i <= 5; i++)
|
|
||||||
{
|
|
||||||
int season = currentSeason + i;
|
|
||||||
|
|
||||||
<option value="@season">
|
|
||||||
Staffel @season
|
|
||||||
</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select class="form-select" value="@Entity.Episode" @onchange="@(e => UpdateEpisode(Entity, e.Value))">
|
|
||||||
@{
|
|
||||||
int currentEpisode = Entity.Episode ?? 1;
|
|
||||||
|
|
||||||
int startOffsetEpisode = currentEpisode > 1 ? -1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@for (int i = startOffsetEpisode; i <= 5; i++)
|
|
||||||
{
|
|
||||||
int episode = currentEpisode + i;
|
|
||||||
|
|
||||||
<option value="@episode">
|
|
||||||
Episode @episode
|
|
||||||
</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
}
|
|
||||||
|
|
||||||
<!-- Beschreibung -->
|
|
||||||
<!--<p class="card-text text-truncate-multiline flex-grow-1 text-muted small mt-1 mb-2">
|
|
||||||
@(!string.IsNullOrWhiteSpace(Entity.Description)
|
|
||||||
? Entity.Description
|
|
||||||
: (Entity.Description ?? "Keine Beschreibung."))
|
|
||||||
</p>
|
|
||||||
-->
|
|
||||||
<!-- Footer Button -->
|
|
||||||
<div class="mt-auto d-flex justify-content-end">
|
|
||||||
<button class="btn btn-outline-secondary btn-sm btn-details" type="button">Details</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Modal (unverändert) -->
|
|
||||||
<div class="modal fade" id="modal-@Entity.Id" tabindex="-1" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">Optionen</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">Optionen...</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code
|
|
||||||
{
|
|
||||||
private List<PrivateEntity> PrivateEntities = new List<PrivateEntity>();
|
|
||||||
private List<UserWatchStatus> userWatchStatuses = new List<UserWatchStatus>();
|
|
||||||
ApplicationUser? AppUser = new();
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
var AuthState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
|
||||||
AppUser = await UserManager.GetUserAsync(AuthState.User);
|
|
||||||
|
|
||||||
if (AppUser != null)
|
|
||||||
{
|
|
||||||
PrivateEntities = await CouchLogDB.PrivateEntities
|
|
||||||
.Where(x => x.UserId == AppUser.Id)
|
|
||||||
.Include(x => x.GlobalEntity)
|
|
||||||
.Include(x => x.UserWatchStatus)
|
|
||||||
.Include(x => x.GlobalEntity.MediaType)
|
|
||||||
.OrderByDescending(Entity => Entity.LastChange ?? Entity.CreationTime)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
userWatchStatuses = await CouchLogDB.UserWatchStatuses.OrderByDescending(Entity => Entity.Id).ToListAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task UpdateWatchStatus(PrivateEntity entity, object? newValue)
|
|
||||||
{
|
|
||||||
// Wir holen uns die gewählte ID aus dem Dropdown
|
|
||||||
if (int.TryParse(newValue?.ToString(), out int newId))
|
|
||||||
{
|
|
||||||
// 1. ID im Objekt aktualisieren
|
|
||||||
entity.UserWatchStatusId = newId;
|
|
||||||
|
|
||||||
// 2. Navigation Property aktualisieren (damit die UI nicht flackert)
|
|
||||||
// Wir suchen das passende Objekt aus der geladenen Liste
|
|
||||||
entity.UserWatchStatus = userWatchStatuses.FirstOrDefault(s => s.Id == newId);
|
|
||||||
|
|
||||||
// 3. Ab in die Datenbank
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task UpdateSeason(PrivateEntity entity, object? newSeasonValue)
|
|
||||||
{
|
|
||||||
if(int.TryParse(newSeasonValue?.ToString(), out int newSeason))
|
|
||||||
{
|
|
||||||
entity.Season = newSeason;
|
|
||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task UpdateEpisode(PrivateEntity entity, object? newEpisodeValue)
|
|
||||||
{
|
|
||||||
if (int.TryParse(newEpisodeValue?.ToString(), out int newEpisode))
|
|
||||||
{
|
|
||||||
entity.Episode = newEpisode;
|
|
||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/* PrivateList.razor.css */
|
|
||||||
|
|
||||||
.private-entity-card {
|
|
||||||
height: 220px;
|
|
||||||
background-color: #fff;
|
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.private-entity-card:hover {
|
|
||||||
transform: translateY(-3px);
|
|
||||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
NEU: Feste Breite für das Bild!
|
|
||||||
150px Breite bei 220px Höhe passt perfekt für Poster.
|
|
||||||
*/
|
|
||||||
.img-wrapper {
|
|
||||||
width: 150px;
|
|
||||||
background-color: #f0f2f5;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bild füllt den Wrapper komplett aus */
|
|
||||||
.entity-img {
|
|
||||||
object-fit: cover;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
/* Positioniert das Bild oben, falls das Format doch leicht abweicht (Köpfe/Titel sind meist oben) */
|
|
||||||
object-position: top center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-truncate-multiline {
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta-text {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-btn {
|
|
||||||
color: #212529;
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
line-height: 1;
|
|
||||||
padding: 0 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-btn:hover {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-details {
|
|
||||||
font-size: 0.7rem;
|
|
||||||
padding: 0.2rem 0.6rem;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
@using CouchLog.Data
|
||||||
|
|
||||||
|
<MudCard Elevation="4">
|
||||||
|
<MudCardContent Class="pa-0">
|
||||||
|
<MudGrid Spacing="0">
|
||||||
|
<!--<editor-fold desc="Poster-Image">-->
|
||||||
|
<MudItem xs="4">
|
||||||
|
<MudImage
|
||||||
|
Src="@PrivateEntity.GlobalEntity.PicturePath"
|
||||||
|
Alt=""
|
||||||
|
ObjectFit="ObjectFit.Cover"
|
||||||
|
Style="width: 100%; height: 100%; min-height: 180px; border-radius: 4px 0 0 4px;" />
|
||||||
|
</MudItem>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
|
||||||
|
<MudItem xs="8">
|
||||||
|
<MudStack Class="pa-3" Spacing="2">
|
||||||
|
<!--<editor-fold desc="Options">-->
|
||||||
|
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween">
|
||||||
|
<MudText Typo="Typo.h6">@PrivateEntity.GlobalEntity.Title</MudText>
|
||||||
|
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Color="Color.Default" Dense="true">
|
||||||
|
<MudMenuItem>Edit</MudMenuItem>
|
||||||
|
<MudMenuItem OnClick="@(() => OnRemove.InvokeAsync())">Remove</MudMenuItem>
|
||||||
|
</MudMenu>
|
||||||
|
</MudStack>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
|
||||||
|
<!--<editor-fold desc="Dropdown-States">-->
|
||||||
|
<MudSelect
|
||||||
|
T="int"
|
||||||
|
Value="PrivateEntity.UserWatchStatus!.Id"
|
||||||
|
ValueChanged="@(newStatusId => OnWatchStatusChange.InvokeAsync(newStatusId))"
|
||||||
|
Dense="true"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Label="">
|
||||||
|
@foreach (var status in UserWatchStatuses)
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="status.Id">@status.Name</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
|
||||||
|
<!--<editor-fold desc="Dropdown-Season">-->
|
||||||
|
<MudSelect
|
||||||
|
T="int?"
|
||||||
|
Value="PrivateEntity.Season"
|
||||||
|
ValueChanged="@(newSeason => OnSeasonChange.InvokeAsync(newSeason))"
|
||||||
|
Dense="true"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Label="">
|
||||||
|
@{
|
||||||
|
int? currentSeason = PrivateEntity.Season ?? 1;
|
||||||
|
int? startOffsetSeason = currentSeason > 1 ? -1 : 0;
|
||||||
|
}
|
||||||
|
@for (int? i = startOffsetSeason; i <= 5; i++)
|
||||||
|
{
|
||||||
|
int? season = currentSeason + i;
|
||||||
|
<MudSelectItem Value="@season">Staffel @season</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
|
||||||
|
<!--<editor-fold desc="Dropdown-Episode">-->
|
||||||
|
<MudSelect
|
||||||
|
T="int?"
|
||||||
|
Value="PrivateEntity.Episode"
|
||||||
|
ValueChanged="@(newEpisode => OnEpisodeChange.InvokeAsync(newEpisode))"
|
||||||
|
Dense="true"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Label="">
|
||||||
|
@{
|
||||||
|
int? currentEpisode = PrivateEntity.Episode ?? 1;
|
||||||
|
int? startOffsetEpisode = currentEpisode > 1 ? -1 : 0;
|
||||||
|
}
|
||||||
|
@for (int? i = startOffsetEpisode; i <= 5; i++)
|
||||||
|
{
|
||||||
|
int? episode = currentEpisode + i;
|
||||||
|
<MudSelectItem Value="@episode">Episode @episode</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
|
||||||
|
<!--<editor-fold desc="Details Button">-->
|
||||||
|
<MudStack Row="true" Justify="Justify.FlexEnd">
|
||||||
|
<MudButton
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Size="Size.Small">
|
||||||
|
Details
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
</MudStack>
|
||||||
|
</MudItem>
|
||||||
|
</MudGrid>
|
||||||
|
</MudCardContent>
|
||||||
|
</MudCard>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[Parameter] public PrivateEntity PrivateEntity { get; set; } = null!;
|
||||||
|
[Parameter] public List<UserWatchStatus> UserWatchStatuses { get; set; } = null!;
|
||||||
|
|
||||||
|
[Parameter] public EventCallback<int> OnWatchStatusChange { get; set; }
|
||||||
|
[Parameter] public EventCallback<int?> OnSeasonChange { get; set; }
|
||||||
|
[Parameter] public EventCallback<int?> OnEpisodeChange { get; set; }
|
||||||
|
|
||||||
|
[Parameter] public EventCallback OnRemove { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
@page "/PrivateList"
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
@using CouchLog.Components.Pages.PrivateList.Components
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
|
||||||
|
@inject ApplicationDbContext CouchLogDb
|
||||||
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
|
@attribute [Authorize]
|
||||||
|
|
||||||
|
<PageTitle>Private List</PageTitle>
|
||||||
|
|
||||||
|
<MudContainer MaxWidth="MaxWidth.False">
|
||||||
|
@*Top of the Page*@
|
||||||
|
<MudContainer>
|
||||||
|
<MudStack Row="true" AlignItems="AlignItems.Center">
|
||||||
|
@*Page Title*@
|
||||||
|
<MudText Typo="Typo.h3" Style="font-weight: bold;">Private List</MudText>
|
||||||
|
</MudStack>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<MudContainer>
|
||||||
|
<MudPaper Class="pa-2" Elevation="1">
|
||||||
|
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
||||||
|
@*Search bar*@
|
||||||
|
<MudTextField @bind-Value="_searchString"
|
||||||
|
Placeholder="Search..."
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Search"
|
||||||
|
Immediate="true"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Margin="Margin.Dense"
|
||||||
|
Style="max-width: 300px;"/>
|
||||||
|
@*Refresh button*@
|
||||||
|
@*<MudTooltip Text="Refresh Entities">
|
||||||
|
<MudIconButton Icon="@Icons.Material.Filled.Refresh" OnClick="RefreshPage"/>
|
||||||
|
</MudTooltip>*@
|
||||||
|
@*More Filters button*@
|
||||||
|
<MudTooltip Text="More filters">
|
||||||
|
<MudIconButton Icon="@(_showFilters
|
||||||
|
? Icons.Material.Filled.ExpandLess
|
||||||
|
: Icons.Material.Filled.FilterList)"
|
||||||
|
OnClick="@(() => _showFilters = !_showFilters)"
|
||||||
|
Color="Color.Default"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</MudStack>
|
||||||
|
<MudCollapse Expanded="_showFilters">
|
||||||
|
No Filters avalible yet!
|
||||||
|
<!--@*Entity allready added*@
|
||||||
|
<MudSwitch @bind-Value="_showAlreadyAddedEntities" Color="Color.Primary">
|
||||||
|
Show already added Entities
|
||||||
|
</MudSwitch>-->
|
||||||
|
@*To be exstendet*@
|
||||||
|
</MudCollapse>
|
||||||
|
</MudPaper>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
<!--<editor-fold desc="Active Watching">-->
|
||||||
|
<MudContainer MaxWidth="MaxWidth.False">
|
||||||
|
<MudText Typo="Typo.h4">Active Watching</MudText>
|
||||||
|
<br/>
|
||||||
|
<MudGrid Spacing="6" Justify="Justify.Center">
|
||||||
|
@foreach (var privateEntity in VisibleActiveWatchingEntities)
|
||||||
|
{
|
||||||
|
<MudItem xs="12" sm="8" md="6" lg="4">
|
||||||
|
<PrivateEntityCard
|
||||||
|
PrivateEntity="privateEntity"
|
||||||
|
UserWatchStatuses="_userWatchStatuses"
|
||||||
|
OnWatchStatusChange="@(newStatusId => ChangeWatchStatus(privateEntity, newStatusId))"
|
||||||
|
OnSeasonChange="@(newSeason => ChangeSeason(privateEntity, newSeason))"
|
||||||
|
OnEpisodeChange="@(newEpisode => ChangeEpisode(privateEntity, newEpisode))"
|
||||||
|
OnRemove="() => RemovePrivateEntity(privateEntity)"
|
||||||
|
/>
|
||||||
|
</MudItem>
|
||||||
|
}
|
||||||
|
</MudGrid>
|
||||||
|
</MudContainer>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<MudContainer>
|
||||||
|
<MudStack AlignItems="AlignItems.Center">
|
||||||
|
<MudPagination Count="@TotalPagesActiveWatching" @bind-Selected="_currentActiveWatchingPage"/>
|
||||||
|
</MudStack>
|
||||||
|
</MudContainer>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<!--<editor-fold desc="Library">-->
|
||||||
|
<MudContainer MaxWidth="MaxWidth.False">
|
||||||
|
<MudText Typo="Typo.h4">Library</MudText>
|
||||||
|
<MudGrid Spacing="6" Justify="Justify.Center">
|
||||||
|
@foreach (var privateEntity in VisibleLibraryEntities)
|
||||||
|
{
|
||||||
|
<MudItem xs="12" sm="8" md="6" lg="4">
|
||||||
|
<PrivateEntityCard
|
||||||
|
PrivateEntity="privateEntity"
|
||||||
|
UserWatchStatuses="_userWatchStatuses"
|
||||||
|
OnWatchStatusChange="@(newStatusId => ChangeWatchStatus(privateEntity, newStatusId))"
|
||||||
|
OnSeasonChange="@(newSeason => ChangeSeason(privateEntity, newSeason))"
|
||||||
|
OnEpisodeChange="@(newEpisode => ChangeEpisode(privateEntity, newEpisode))"
|
||||||
|
OnRemove="() => RemovePrivateEntity(privateEntity)"
|
||||||
|
/>
|
||||||
|
</MudItem>
|
||||||
|
}
|
||||||
|
</MudGrid>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<MudContainer>
|
||||||
|
<MudStack AlignItems="AlignItems.Center">
|
||||||
|
<MudPagination Count="@TotalPagesLibrary" @bind-Selected="_currentLibraryPage"/>
|
||||||
|
</MudStack>
|
||||||
|
</MudContainer>
|
||||||
|
<!--</editor-fold>-->
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
//Filter
|
||||||
|
private string? _searchString;
|
||||||
|
private bool _showFilters;
|
||||||
|
private bool _showAlreadyAddedEntities = false;
|
||||||
|
private IEnumerable<PrivateEntity> FiltertGlobalEntities => _privateEntities.Where(entity =>
|
||||||
|
(string.IsNullOrWhiteSpace(_searchString) || entity.GlobalEntity.Title.Contains(_searchString, StringComparison.OrdinalIgnoreCase)) //Search bar
|
||||||
|
);
|
||||||
|
|
||||||
|
//Paging Active Watching
|
||||||
|
private int _currentActiveWatchingPage = 1;
|
||||||
|
private readonly int _pageSizeActiveWatching = 12;
|
||||||
|
private int TotalPagesActiveWatching => (int)Math.Ceiling(ActiveWatchingEntities.Count() / (double)_pageSizeActiveWatching);
|
||||||
|
private IEnumerable<PrivateEntity> VisibleActiveWatchingEntities => ActiveWatchingEntities.Skip((_currentActiveWatchingPage - 1) * _pageSizeActiveWatching).Take(_pageSizeActiveWatching);
|
||||||
|
|
||||||
|
//Paging Library
|
||||||
|
private int _currentLibraryPage = 1;
|
||||||
|
private readonly int _pageSizeLibrary = 12;
|
||||||
|
private int TotalPagesLibrary => (int)Math.Ceiling(LibraryEntities.Count() / (double)_pageSizeLibrary);
|
||||||
|
private IEnumerable<PrivateEntity> VisibleLibraryEntities => LibraryEntities.Skip((_currentLibraryPage - 1) * _pageSizeLibrary).Take(_pageSizeLibrary);
|
||||||
|
|
||||||
|
//User
|
||||||
|
private ApplicationUser? _appUser;
|
||||||
|
|
||||||
|
//Entities
|
||||||
|
private List<PrivateEntity> _privateEntities = [];
|
||||||
|
private List<UserWatchStatus> _userWatchStatuses = [];
|
||||||
|
|
||||||
|
private IEnumerable<PrivateEntity> ActiveWatchingEntities => FiltertGlobalEntities.Where(x => x.UserWatchStatus?.Name == "Watching").ToList();
|
||||||
|
private IEnumerable<PrivateEntity> LibraryEntities => FiltertGlobalEntities.Where(x => x.UserWatchStatus?.Name != "Watching").ToList();
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await GetPrivateEntities();
|
||||||
|
|
||||||
|
_userWatchStatuses = await CouchLogDb.UserWatchStatuses.OrderBy(entity => entity.Id).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetPrivateEntities()
|
||||||
|
{
|
||||||
|
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
|
_appUser = await UserManager.GetUserAsync(authState.User);
|
||||||
|
|
||||||
|
if (_appUser != null)
|
||||||
|
{
|
||||||
|
_privateEntities = await CouchLogDb.PrivateEntities
|
||||||
|
.Where(x => x.UserId == _appUser.Id)
|
||||||
|
.Include(x => x.GlobalEntity)
|
||||||
|
.Include(x => x.UserWatchStatus)
|
||||||
|
.Include(x => x.GlobalEntity.MediaType)
|
||||||
|
.OrderByDescending(entity => entity.LastChange ?? entity.CreationTime)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task RefreshPages()
|
||||||
|
{
|
||||||
|
_currentLibraryPage = 1;
|
||||||
|
_currentActiveWatchingPage = 1;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangeWatchStatus(PrivateEntity privateEntity, int newUserWatchStatusId)
|
||||||
|
{
|
||||||
|
privateEntity.UserWatchStatus = _userWatchStatuses.FirstOrDefault(s => s.Id == newUserWatchStatusId);
|
||||||
|
await CouchLogDb.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangeSeason(PrivateEntity privateEntity, int? newSeason)
|
||||||
|
{
|
||||||
|
privateEntity.Season = newSeason;
|
||||||
|
await CouchLogDb.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangeEpisode(PrivateEntity privateEntity, int? newEpisode)
|
||||||
|
{
|
||||||
|
privateEntity.Episode = newEpisode;
|
||||||
|
await CouchLogDb.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task RemovePrivateEntity(PrivateEntity privateEntity)
|
||||||
|
{
|
||||||
|
CouchLogDb.PrivateEntities.Remove(privateEntity);
|
||||||
|
await CouchLogDb.SaveChangesAsync();
|
||||||
|
await GetPrivateEntities();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,3 +9,4 @@
|
|||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
@using CouchLog
|
@using CouchLog
|
||||||
@using CouchLog.Components
|
@using CouchLog.Components
|
||||||
|
@using MudBlazor
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<PackAsTool>True</PackAsTool>
|
<PackAsTool>True</PackAsTool>
|
||||||
|
<Version>0.1.0-nightly.10</Version>
|
||||||
|
<Authors>Penry</Authors>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -77,6 +79,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="MudBlazor" Version="9.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 18
|
# Visual Studio Version 18
|
||||||
VisualStudioVersion = 18.1.11304.174 d18.0
|
VisualStudioVersion = 18.1.11304.174
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CouchLog", "CouchLog.csproj", "{4FBF15C3-5FC5-4605-9EBC-3F7DA1ADC47A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CouchLog", "CouchLog.csproj", "{4FBF15C3-5FC5-4605-9EBC-3F7DA1ADC47A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
@@ -23,5 +23,9 @@ namespace CouchLog.Data
|
|||||||
public DbSet<SharedListEntity> SharedListEntities { get; set; }
|
public DbSet<SharedListEntity> SharedListEntities { get; set; }
|
||||||
public DbSet<SharedListLabel> SharedListLabels { get; set; }
|
public DbSet<SharedListLabel> SharedListLabels { get; set; }
|
||||||
public DbSet<SharedWatchStatus> SharedWatchStatuses { get; set; }
|
public DbSet<SharedWatchStatus> SharedWatchStatuses { get; set; }
|
||||||
|
|
||||||
|
//Settings
|
||||||
|
public DbSet<CouchLogState> CouchLogState { get; set; }
|
||||||
|
public DbSet<AccountsSettings> AccountsSettings { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,6 @@ namespace CouchLog.Data
|
|||||||
[ForeignKey(nameof(CreatorId))]
|
[ForeignKey(nameof(CreatorId))]
|
||||||
public virtual ApplicationUser User { get; set; } = null!;
|
public virtual ApplicationUser User { get; set; } = null!;
|
||||||
|
|
||||||
public virtual ICollection<LinkTablePrivateLabel> LinkTablePrivateLabels { get; set; } = new List<LinkTablePrivateLabel>();
|
public virtual ICollection<LinkTablePrivateLabel> LinkTablePrivateLabels { get; set; } = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace CouchLog.Data
|
||||||
|
{
|
||||||
|
public class AccountsSettings
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public bool IsRegistrationAllowed { get; set; }
|
||||||
|
|
||||||
|
//More Options that can be added
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace CouchLog.Data
|
||||||
|
{
|
||||||
|
public class CouchLogState
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public bool IsInitialized { get; set; }
|
||||||
|
public DateTime? InitializationDate { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,978 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using CouchLog.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace CouchLog.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20251229004324_CouchLogState")]
|
||||||
|
partial class CouchLogState
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "10.0.1");
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.CouchLogState", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("InitializationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsInitialized")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CouchLogState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Genres");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CreatorId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPrivate")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PicturePath")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("TypeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreatorId");
|
||||||
|
|
||||||
|
b.HasIndex("TypeId");
|
||||||
|
|
||||||
|
b.ToTable("GlobalEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CreatorId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreatorId");
|
||||||
|
|
||||||
|
b.ToTable("Labels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableGlobalGenre", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnOrder(0);
|
||||||
|
|
||||||
|
b.Property<int>("GenreId")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnOrder(1);
|
||||||
|
|
||||||
|
b.HasKey("GlobalEntityId", "GenreId");
|
||||||
|
|
||||||
|
b.HasIndex("GenreId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableGlobalGenre");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrivateEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("LabelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("PrivateEntityId", "LabelId");
|
||||||
|
|
||||||
|
b.HasIndex("LabelId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTablePrivateLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateStreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrivateEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("StreamingPlatformId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("SharedListEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("PrivateEntityId", "StreamingPlatformId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("StreamingPlatformId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTablePrivateStreamingPlatform");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SharedListLabelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("SharedListLabelId", "SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListEntityId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableSharedLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("SharedListId", "UserId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableSharedUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.MediaType", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("MediaType");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Episode")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Favorite")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Rating")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("Season")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("UserWatchStatusId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GlobalEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.HasIndex("UserWatchStatusId");
|
||||||
|
|
||||||
|
b.ToTable("PrivateEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedList", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(150)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SharedLists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Episode")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Favorite")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Season")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("SharedWatchStatusId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GlobalEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedWatchStatusId");
|
||||||
|
|
||||||
|
b.ToTable("SharedListEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.ToTable("SharedListLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ColorCode")
|
||||||
|
.HasMaxLength(7)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.ToTable("SharedWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.StreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PicturePath")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("StreamingPlatforms");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.UserWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ColorCode")
|
||||||
|
.HasMaxLength(7)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UserWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("CreatedGlobalEntities")
|
||||||
|
.HasForeignKey("CreatorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.MediaType", "MediaType")
|
||||||
|
.WithMany("GlobalEntities")
|
||||||
|
.HasForeignKey("TypeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("MediaType");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("CreatedLabels")
|
||||||
|
.HasForeignKey("CreatorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableGlobalGenre", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.Genre", "Genre")
|
||||||
|
.WithMany("LinkTableGlobalGenres")
|
||||||
|
.HasForeignKey("GenreId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("LinkTableGlobalGenres")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Genre");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.Label", "Label")
|
||||||
|
.WithMany("LinkTablePrivateLabels")
|
||||||
|
.HasForeignKey("LabelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.PrivateEntity", "PrivateEntity")
|
||||||
|
.WithMany("PrivateEntityLabels")
|
||||||
|
.HasForeignKey("PrivateEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Label");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateStreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.PrivateEntity", "PrivateEntity")
|
||||||
|
.WithMany("PrivateStreamingPlatforms")
|
||||||
|
.HasForeignKey("PrivateEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedListEntity", null)
|
||||||
|
.WithMany("LinkTablePrivateStreamingPlatforms")
|
||||||
|
.HasForeignKey("SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.StreamingPlatform", "StreamingPlatform")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("StreamingPlatformId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntity");
|
||||||
|
|
||||||
|
b.Navigation("StreamingPlatform");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedListEntity", "SharedListEntity")
|
||||||
|
.WithMany("LinkTableSharedLabels")
|
||||||
|
.HasForeignKey("SharedListEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedListLabel", "SharedListLabel")
|
||||||
|
.WithMany("LinkTableSharedLabels")
|
||||||
|
.HasForeignKey("SharedListLabelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedListEntity");
|
||||||
|
|
||||||
|
b.Navigation("SharedListLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedUser", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListUsers")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("LinkTableSharedUsers")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("PrivateEntities")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("PrivateEntities")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.UserWatchStatus", "UserWatchStatus")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserWatchStatusId");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
|
||||||
|
b.Navigation("UserWatchStatus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedWatchStatus", "SharedWatchStatus")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("SharedWatchStatusId");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
|
||||||
|
b.Navigation("SharedWatchStatus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListLabels")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedWatchStatuses")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("CreatedGlobalEntities");
|
||||||
|
|
||||||
|
b.Navigation("CreatedLabels");
|
||||||
|
|
||||||
|
b.Navigation("LinkTableSharedUsers");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableGlobalGenres");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableGlobalGenres");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntities");
|
||||||
|
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTablePrivateLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.MediaType", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("GlobalEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("PrivateEntityLabels");
|
||||||
|
|
||||||
|
b.Navigation("PrivateStreamingPlatforms");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedList", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
|
||||||
|
b.Navigation("SharedListLabels");
|
||||||
|
|
||||||
|
b.Navigation("SharedListUsers");
|
||||||
|
|
||||||
|
b.Navigation("SharedWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTablePrivateStreamingPlatforms");
|
||||||
|
|
||||||
|
b.Navigation("LinkTableSharedLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableSharedLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace CouchLog.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class CouchLogState : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "CouchLogState",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
IsInitialized = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
InitializationDate = table.Column<DateTime>(type: "TEXT", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_CouchLogState", x => x.Id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "CouchLogState");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,992 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using CouchLog.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace CouchLog.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20260103202104_AccountsSettings")]
|
||||||
|
partial class AccountsSettings
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "10.0.1");
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.AccountsSettings", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRegistrationAllowed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("AccountsSettings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.CouchLogState", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("InitializationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsInitialized")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CouchLogState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Genres");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CreatorId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPrivate")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PicturePath")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("TypeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreatorId");
|
||||||
|
|
||||||
|
b.HasIndex("TypeId");
|
||||||
|
|
||||||
|
b.ToTable("GlobalEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CreatorId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreatorId");
|
||||||
|
|
||||||
|
b.ToTable("Labels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableGlobalGenre", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnOrder(0);
|
||||||
|
|
||||||
|
b.Property<int>("GenreId")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnOrder(1);
|
||||||
|
|
||||||
|
b.HasKey("GlobalEntityId", "GenreId");
|
||||||
|
|
||||||
|
b.HasIndex("GenreId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableGlobalGenre");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrivateEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("LabelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("PrivateEntityId", "LabelId");
|
||||||
|
|
||||||
|
b.HasIndex("LabelId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTablePrivateLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateStreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrivateEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("StreamingPlatformId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("SharedListEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("PrivateEntityId", "StreamingPlatformId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("StreamingPlatformId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTablePrivateStreamingPlatform");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SharedListLabelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("SharedListLabelId", "SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListEntityId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableSharedLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("SharedListId", "UserId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableSharedUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.MediaType", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("MediaType");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Episode")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Favorite")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Rating")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("Season")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("UserWatchStatusId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GlobalEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.HasIndex("UserWatchStatusId");
|
||||||
|
|
||||||
|
b.ToTable("PrivateEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedList", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(150)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SharedLists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Episode")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Favorite")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Season")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("SharedWatchStatusId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GlobalEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedWatchStatusId");
|
||||||
|
|
||||||
|
b.ToTable("SharedListEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.ToTable("SharedListLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ColorCode")
|
||||||
|
.HasMaxLength(7)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.ToTable("SharedWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.StreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PicturePath")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("StreamingPlatforms");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.UserWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ColorCode")
|
||||||
|
.HasMaxLength(7)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UserWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("CreatedGlobalEntities")
|
||||||
|
.HasForeignKey("CreatorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.MediaType", "MediaType")
|
||||||
|
.WithMany("GlobalEntities")
|
||||||
|
.HasForeignKey("TypeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("MediaType");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("CreatedLabels")
|
||||||
|
.HasForeignKey("CreatorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableGlobalGenre", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.Genre", "Genre")
|
||||||
|
.WithMany("LinkTableGlobalGenres")
|
||||||
|
.HasForeignKey("GenreId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("LinkTableGlobalGenres")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Genre");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.Label", "Label")
|
||||||
|
.WithMany("LinkTablePrivateLabels")
|
||||||
|
.HasForeignKey("LabelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.PrivateEntity", "PrivateEntity")
|
||||||
|
.WithMany("PrivateEntityLabels")
|
||||||
|
.HasForeignKey("PrivateEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Label");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateStreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.PrivateEntity", "PrivateEntity")
|
||||||
|
.WithMany("PrivateStreamingPlatforms")
|
||||||
|
.HasForeignKey("PrivateEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedListEntity", null)
|
||||||
|
.WithMany("LinkTablePrivateStreamingPlatforms")
|
||||||
|
.HasForeignKey("SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.StreamingPlatform", "StreamingPlatform")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("StreamingPlatformId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntity");
|
||||||
|
|
||||||
|
b.Navigation("StreamingPlatform");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedListEntity", "SharedListEntity")
|
||||||
|
.WithMany("LinkTableSharedLabels")
|
||||||
|
.HasForeignKey("SharedListEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedListLabel", "SharedListLabel")
|
||||||
|
.WithMany("LinkTableSharedLabels")
|
||||||
|
.HasForeignKey("SharedListLabelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedListEntity");
|
||||||
|
|
||||||
|
b.Navigation("SharedListLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedUser", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListUsers")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("LinkTableSharedUsers")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("PrivateEntities")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("PrivateEntities")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.UserWatchStatus", "UserWatchStatus")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserWatchStatusId");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
|
||||||
|
b.Navigation("UserWatchStatus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedWatchStatus", "SharedWatchStatus")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("SharedWatchStatusId");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
|
||||||
|
b.Navigation("SharedWatchStatus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListLabels")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedWatchStatuses")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("CreatedGlobalEntities");
|
||||||
|
|
||||||
|
b.Navigation("CreatedLabels");
|
||||||
|
|
||||||
|
b.Navigation("LinkTableSharedUsers");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableGlobalGenres");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableGlobalGenres");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntities");
|
||||||
|
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTablePrivateLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.MediaType", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("GlobalEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("PrivateEntityLabels");
|
||||||
|
|
||||||
|
b.Navigation("PrivateStreamingPlatforms");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedList", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
|
||||||
|
b.Navigation("SharedListLabels");
|
||||||
|
|
||||||
|
b.Navigation("SharedListUsers");
|
||||||
|
|
||||||
|
b.Navigation("SharedWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTablePrivateStreamingPlatforms");
|
||||||
|
|
||||||
|
b.Navigation("LinkTableSharedLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableSharedLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace CouchLog.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AccountsSettings : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AccountsSettings",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
IsRegistrationAllowed = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AccountsSettings", x => x.Id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AccountsSettings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,992 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using CouchLog.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace CouchLog.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
|
[Migration("20260104151950_FixAccountsSettingsKey")]
|
||||||
|
partial class FixAccountsSettingsKey
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "10.0.1");
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.AccountsSettings", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRegistrationAllowed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("AccountsSettings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.CouchLogState", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("InitializationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsInitialized")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CouchLogState");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Genres");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CreatorId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPrivate")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PicturePath")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("TypeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreatorId");
|
||||||
|
|
||||||
|
b.HasIndex("TypeId");
|
||||||
|
|
||||||
|
b.ToTable("GlobalEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CreatorId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreatorId");
|
||||||
|
|
||||||
|
b.ToTable("Labels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableGlobalGenre", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnOrder(0);
|
||||||
|
|
||||||
|
b.Property<int>("GenreId")
|
||||||
|
.HasColumnType("INTEGER")
|
||||||
|
.HasColumnOrder(1);
|
||||||
|
|
||||||
|
b.HasKey("GlobalEntityId", "GenreId");
|
||||||
|
|
||||||
|
b.HasIndex("GenreId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableGlobalGenre");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrivateEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("LabelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("PrivateEntityId", "LabelId");
|
||||||
|
|
||||||
|
b.HasIndex("LabelId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTablePrivateLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateStreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PrivateEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("StreamingPlatformId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("SharedListEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("PrivateEntityId", "StreamingPlatformId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("StreamingPlatformId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTablePrivateStreamingPlatform");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SharedListLabelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("SharedListLabelId", "SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListEntityId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableSharedLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("SharedListId", "UserId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("LinkTableSharedUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.MediaType", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("MediaType");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Episode")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Favorite")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Rating")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("Season")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("UserWatchStatusId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GlobalEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.HasIndex("UserWatchStatusId");
|
||||||
|
|
||||||
|
b.ToTable("PrivateEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedList", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(150)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("SharedLists");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Episode")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Favorite")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("GlobalEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("Season")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("SharedWatchStatusId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GlobalEntityId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.HasIndex("SharedWatchStatusId");
|
||||||
|
|
||||||
|
b.ToTable("SharedListEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.ToTable("SharedListLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ColorCode")
|
||||||
|
.HasMaxLength(7)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SharedListId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SharedListId");
|
||||||
|
|
||||||
|
b.ToTable("SharedWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.StreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PicturePath")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("StreamingPlatforms");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.UserWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ColorCode")
|
||||||
|
.HasMaxLength(7)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastChange")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("UserWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("RoleId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("CreatedGlobalEntities")
|
||||||
|
.HasForeignKey("CreatorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.MediaType", "MediaType")
|
||||||
|
.WithMany("GlobalEntities")
|
||||||
|
.HasForeignKey("TypeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("MediaType");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("CreatedLabels")
|
||||||
|
.HasForeignKey("CreatorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableGlobalGenre", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.Genre", "Genre")
|
||||||
|
.WithMany("LinkTableGlobalGenres")
|
||||||
|
.HasForeignKey("GenreId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("LinkTableGlobalGenres")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Genre");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.Label", "Label")
|
||||||
|
.WithMany("LinkTablePrivateLabels")
|
||||||
|
.HasForeignKey("LabelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.PrivateEntity", "PrivateEntity")
|
||||||
|
.WithMany("PrivateEntityLabels")
|
||||||
|
.HasForeignKey("PrivateEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Label");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTablePrivateStreamingPlatform", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.PrivateEntity", "PrivateEntity")
|
||||||
|
.WithMany("PrivateStreamingPlatforms")
|
||||||
|
.HasForeignKey("PrivateEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedListEntity", null)
|
||||||
|
.WithMany("LinkTablePrivateStreamingPlatforms")
|
||||||
|
.HasForeignKey("SharedListEntityId");
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.StreamingPlatform", "StreamingPlatform")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("StreamingPlatformId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntity");
|
||||||
|
|
||||||
|
b.Navigation("StreamingPlatform");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedListEntity", "SharedListEntity")
|
||||||
|
.WithMany("LinkTableSharedLabels")
|
||||||
|
.HasForeignKey("SharedListEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedListLabel", "SharedListLabel")
|
||||||
|
.WithMany("LinkTableSharedLabels")
|
||||||
|
.HasForeignKey("SharedListLabelId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedListEntity");
|
||||||
|
|
||||||
|
b.Navigation("SharedListLabel");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.LinkTableSharedUser", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListUsers")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("LinkTableSharedUsers")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("PrivateEntities")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", "User")
|
||||||
|
.WithMany("PrivateEntities")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.UserWatchStatus", "UserWatchStatus")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserWatchStatusId");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
|
||||||
|
b.Navigation("UserWatchStatus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.GlobalEntity", "GlobalEntity")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("GlobalEntityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.SharedWatchStatus", "SharedWatchStatus")
|
||||||
|
.WithMany("SharedListEntities")
|
||||||
|
.HasForeignKey("SharedWatchStatusId");
|
||||||
|
|
||||||
|
b.Navigation("GlobalEntity");
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
|
||||||
|
b.Navigation("SharedWatchStatus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedListLabels")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.SharedList", "SharedList")
|
||||||
|
.WithMany("SharedWatchStatuses")
|
||||||
|
.HasForeignKey("SharedListId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SharedList");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("CouchLog.Data.ApplicationUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("CreatedGlobalEntities");
|
||||||
|
|
||||||
|
b.Navigation("CreatedLabels");
|
||||||
|
|
||||||
|
b.Navigation("LinkTableSharedUsers");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableGlobalGenres");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.GlobalEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableGlobalGenres");
|
||||||
|
|
||||||
|
b.Navigation("PrivateEntities");
|
||||||
|
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.Label", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTablePrivateLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.MediaType", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("GlobalEntities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.PrivateEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("PrivateEntityLabels");
|
||||||
|
|
||||||
|
b.Navigation("PrivateStreamingPlatforms");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedList", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
|
||||||
|
b.Navigation("SharedListLabels");
|
||||||
|
|
||||||
|
b.Navigation("SharedListUsers");
|
||||||
|
|
||||||
|
b.Navigation("SharedWatchStatuses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTablePrivateStreamingPlatforms");
|
||||||
|
|
||||||
|
b.Navigation("LinkTableSharedLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedListLabel", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("LinkTableSharedLabels");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.SharedWatchStatus", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("SharedListEntities");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace CouchLog.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class FixAccountsSettingsKey : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,20 @@ namespace CouchLog.Migrations
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder.HasAnnotation("ProductVersion", "10.0.1");
|
modelBuilder.HasAnnotation("ProductVersion", "10.0.1");
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.AccountsSettings", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRegistrationAllowed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("AccountsSettings");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
modelBuilder.Entity("CouchLog.Data.ApplicationUser", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
@@ -81,6 +95,23 @@ namespace CouchLog.Migrations
|
|||||||
b.ToTable("AspNetUsers", (string)null);
|
b.ToTable("AspNetUsers", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("CouchLog.Data.CouchLogState", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("InitializationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsInitialized")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("CouchLogState");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
modelBuilder.Entity("CouchLog.Data.Genre", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
|||||||
+75
-28
@@ -1,23 +1,52 @@
|
|||||||
using CouchLog.Data;
|
using CouchLog.Data;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace CouchLog
|
namespace CouchLog
|
||||||
{
|
{
|
||||||
public class OnStartUp
|
public class OnStartUp(ApplicationDbContext CouchLogDB, RoleManager<IdentityRole> RoleManager)
|
||||||
{
|
{
|
||||||
private ApplicationDbContext CouchLogDB;
|
private readonly ApplicationDbContext CouchLogDB = CouchLogDB;
|
||||||
|
private readonly RoleManager<IdentityRole> RoleManager = RoleManager;
|
||||||
|
|
||||||
public OnStartUp(ApplicationDbContext CouchLogDB)
|
public async Task CreateRoles()
|
||||||
{
|
{
|
||||||
this.CouchLogDB = CouchLogDB;
|
string[] roleNames = ["Admin", "User"];
|
||||||
|
IdentityResult roleResult;
|
||||||
|
|
||||||
|
foreach (var roleName in roleNames)
|
||||||
|
{
|
||||||
|
var roleExist = await RoleManager.RoleExistsAsync(roleName);
|
||||||
|
if (!roleExist)
|
||||||
|
{
|
||||||
|
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddBasicDatabaseEntries()
|
public async Task CreateStanardSettings()
|
||||||
|
{
|
||||||
|
if(!CouchLogDB.AccountsSettings.Any())
|
||||||
|
{
|
||||||
|
AccountsSettings accountsSettings = new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
IsRegistrationAllowed = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
await CouchLogDB.AccountsSettings.AddAsync(accountsSettings);
|
||||||
|
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddBasicDatabaseEntries()
|
||||||
{
|
{
|
||||||
//##################
|
//##################
|
||||||
//### MediaTypes ###
|
//### MediaTypes ###
|
||||||
//##################
|
//##################
|
||||||
List<MediaType> MediaTypes = new List<MediaType>
|
List<MediaType> MediaTypes =
|
||||||
{
|
[
|
||||||
//Video based
|
//Video based
|
||||||
new() { Name="Movie" },
|
new() { Name="Movie" },
|
||||||
new() { Name="Series" },
|
new() { Name="Series" },
|
||||||
@@ -38,23 +67,24 @@ namespace CouchLog
|
|||||||
//Text based
|
//Text based
|
||||||
new() { Name = "Book" },
|
new() { Name = "Book" },
|
||||||
new() { Name = "Comic" },
|
new() { Name = "Comic" },
|
||||||
};
|
];
|
||||||
|
|
||||||
foreach (MediaType MediaType in MediaTypes)
|
foreach (MediaType MediaType in MediaTypes)
|
||||||
{
|
{
|
||||||
if(!CouchLogDB.MediaType.Any(m => m.Name == MediaType.Name))
|
if(!await CouchLogDB.MediaType.AnyAsync(m => m.Name == MediaType.Name))
|
||||||
{
|
{
|
||||||
CouchLogDB.MediaType.Add(MediaType);
|
await CouchLogDB.MediaType.AddAsync(MediaType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//##############
|
//##############
|
||||||
//### Genres ###
|
//### Genres ###
|
||||||
//##############
|
//##############
|
||||||
List<Genre> Genres = new List<Genre>
|
List<Genre> Genres =
|
||||||
{
|
[
|
||||||
new() { Name = "Action", CreationTime = DateTime.Now },
|
new() { Name = "Action", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Animation", CreationTime = DateTime.Now },
|
new() { Name = "Animation", CreationTime = DateTime.Now },
|
||||||
|
new() { Name = "Adventure", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Comedy", CreationTime = DateTime.Now },
|
new() { Name = "Comedy", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Crime", CreationTime = DateTime.Now },
|
new() { Name = "Crime", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Drama", CreationTime = DateTime.Now },
|
new() { Name = "Drama", CreationTime = DateTime.Now },
|
||||||
@@ -69,13 +99,13 @@ namespace CouchLog
|
|||||||
new() { Name = "Thriller", CreationTime = DateTime.Now },
|
new() { Name = "Thriller", CreationTime = DateTime.Now },
|
||||||
new() { Name = "War", CreationTime = DateTime.Now },
|
new() { Name = "War", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Western", CreationTime = DateTime.Now },
|
new() { Name = "Western", CreationTime = DateTime.Now },
|
||||||
};
|
];
|
||||||
|
|
||||||
foreach(Genre Genre in Genres)
|
foreach(Genre Genre in Genres)
|
||||||
{
|
{
|
||||||
if(!CouchLogDB.Genres.Any(m => m.Name == Genre.Name))
|
if(! await CouchLogDB.Genres.AnyAsync(m => m.Name == Genre.Name))
|
||||||
{
|
{
|
||||||
CouchLogDB.Genres.Add(Genre);
|
await CouchLogDB.Genres.AddAsync(Genre);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +113,8 @@ namespace CouchLog
|
|||||||
//##########################
|
//##########################
|
||||||
//### StreamingPlatforms ###
|
//### StreamingPlatforms ###
|
||||||
//##########################
|
//##########################
|
||||||
List<StreamingPlatform> StreamingPlatforms = new List<StreamingPlatform>
|
List<StreamingPlatform> StreamingPlatforms =
|
||||||
{
|
[
|
||||||
new() { Name = "Netflix", PicturePath="StreamingPlatforms/Netflix.png", CreationTime = DateTime.Now },
|
new() { Name = "Netflix", PicturePath="StreamingPlatforms/Netflix.png", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Prime Video", PicturePath="StreamingPlatforms/Prime-Video.png", CreationTime = DateTime.Now },
|
new() { Name = "Prime Video", PicturePath="StreamingPlatforms/Prime-Video.png", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Disney+", PicturePath="StreamingPlatforms/Disney+.png", CreationTime = DateTime.Now },
|
new() { Name = "Disney+", PicturePath="StreamingPlatforms/Disney+.png", CreationTime = DateTime.Now },
|
||||||
@@ -92,38 +122,55 @@ namespace CouchLog
|
|||||||
new() { Name = "WOW TV", PicturePath="StreamingPlatforms/WOWTV.png", CreationTime = DateTime.Now },
|
new() { Name = "WOW TV", PicturePath="StreamingPlatforms/WOWTV.png", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Paramount+", PicturePath="StreamingPlatforms/Paramount+.png", CreationTime = DateTime.Now },
|
new() { Name = "Paramount+", PicturePath="StreamingPlatforms/Paramount+.png", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Joyn", PicturePath="StreamingPlatforms/Joyn.png", CreationTime = DateTime.Now },
|
new() { Name = "Joyn", PicturePath="StreamingPlatforms/Joyn.png", CreationTime = DateTime.Now },
|
||||||
};
|
];
|
||||||
|
|
||||||
foreach(StreamingPlatform StreamingPlatform in StreamingPlatforms)
|
foreach(StreamingPlatform StreamingPlatform in StreamingPlatforms)
|
||||||
{
|
{
|
||||||
if(!CouchLogDB.StreamingPlatforms.Any(m => m.Name == StreamingPlatform.Name))
|
if(! await CouchLogDB.StreamingPlatforms.AnyAsync(m => m.Name == StreamingPlatform.Name))
|
||||||
{
|
{
|
||||||
CouchLogDB.StreamingPlatforms.Add(StreamingPlatform);
|
await CouchLogDB.StreamingPlatforms.AddAsync(StreamingPlatform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//##########################
|
//##########################
|
||||||
//###### WatchStates #######
|
//###### WatchStates #######
|
||||||
//##########################
|
//##########################
|
||||||
List<UserWatchStatus> UserWatchStatuses = new List<UserWatchStatus>
|
List<UserWatchStatus> UserWatchStatuses =
|
||||||
{
|
[
|
||||||
new() { Name = "Not watched", CreationTime = DateTime.Now },
|
new() { Name = "Not watched", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Started", CreationTime = DateTime.Now },
|
new() { Name = "Watching", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Finished", CreationTime = DateTime.Now },
|
new() { Name = "Finished", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Paused", CreationTime = DateTime.Now },
|
new() { Name = "Waiting for next Season", CreationTime = DateTime.Now },
|
||||||
new() { Name = "Aborted", CreationTime= DateTime.Now },
|
new() { Name = "Aborted", CreationTime= DateTime.Now },
|
||||||
};
|
];
|
||||||
|
|
||||||
foreach(UserWatchStatus UserWatchStatus in UserWatchStatuses)
|
foreach(UserWatchStatus UserWatchStatus in UserWatchStatuses)
|
||||||
{
|
{
|
||||||
if(!CouchLogDB.UserWatchStatuses.Any(m => m.Name == UserWatchStatus.Name))
|
if(! await CouchLogDB.UserWatchStatuses.AnyAsync(m => m.Name == UserWatchStatus.Name))
|
||||||
{
|
{
|
||||||
CouchLogDB.UserWatchStatuses.Add(UserWatchStatus);
|
await CouchLogDB.UserWatchStatuses.AddAsync(UserWatchStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#################################################
|
||||||
|
//###### Old-Things that need to be deleted #######
|
||||||
|
//#################################################
|
||||||
|
List<UserWatchStatus> oldUserWatchStatuses =
|
||||||
|
[
|
||||||
|
new() { Name = "Started" , CreationTime = DateTime.Now },
|
||||||
|
];
|
||||||
|
|
||||||
CouchLogDB.SaveChanges();
|
foreach(UserWatchStatus oldUserWatchStatus in oldUserWatchStatuses)
|
||||||
|
{
|
||||||
|
UserWatchStatus? toDeletedUserWatchStatus = await CouchLogDB.UserWatchStatuses.FirstOrDefaultAsync(m => m.Name == oldUserWatchStatus.Name);
|
||||||
|
|
||||||
|
if(toDeletedUserWatchStatus != null)
|
||||||
|
{
|
||||||
|
CouchLogDB.UserWatchStatuses.Remove(toDeletedUserWatchStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-84
@@ -5,6 +5,8 @@ using CouchLog.Components;
|
|||||||
using CouchLog.Components.Account;
|
using CouchLog.Components.Account;
|
||||||
using CouchLog.Data;
|
using CouchLog.Data;
|
||||||
using CouchLog;
|
using CouchLog;
|
||||||
|
using MudBlazor;
|
||||||
|
using MudBlazor.Services;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -35,6 +37,10 @@ builder.Services.AddIdentityCore<ApplicationUser>(options => options.SignIn.Requ
|
|||||||
.AddDefaultTokenProviders();
|
.AddDefaultTokenProviders();
|
||||||
|
|
||||||
builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
|
builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
|
||||||
|
builder.Services.AddMudServices(config =>
|
||||||
|
{
|
||||||
|
config.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.BottomCenter;
|
||||||
|
});
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
@@ -65,91 +71,12 @@ using (var scope = app.Services.CreateScope())
|
|||||||
var CouchLogDB = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
var CouchLogDB = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||||
CouchLogDB.Database.Migrate();
|
CouchLogDB.Database.Migrate();
|
||||||
|
|
||||||
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
|
var RoleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
|
||||||
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
|
|
||||||
|
|
||||||
string[] roleNames = { "Admin", "User" };
|
OnStartUp onStartUp = new(CouchLogDB, RoleManager);
|
||||||
IdentityResult roleResult;
|
await onStartUp.CreateRoles();
|
||||||
|
await onStartUp.AddBasicDatabaseEntries();
|
||||||
foreach (var roleName in roleNames)
|
await onStartUp.CreateStanardSettings();
|
||||||
{
|
|
||||||
var roleExist = await roleManager.RoleExistsAsync(roleName);
|
|
||||||
if (!roleExist)
|
|
||||||
{
|
|
||||||
roleResult = await roleManager.CreateAsync(new IdentityRole(roleName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var adminUsername = "Admin";
|
|
||||||
var normalUsername = "User";
|
|
||||||
var adminPassword = "EinSehrSicheresPasswort123!";
|
|
||||||
|
|
||||||
var adminUser = await userManager.FindByNameAsync(adminUsername);
|
|
||||||
var normalUser = await userManager.FindByNameAsync(normalUsername);
|
|
||||||
|
|
||||||
if (adminUser == null)
|
|
||||||
{
|
|
||||||
adminUser = new ApplicationUser
|
|
||||||
{
|
|
||||||
UserName = adminUsername,
|
|
||||||
EmailConfirmed = true
|
|
||||||
};
|
|
||||||
var createResult = await userManager.CreateAsync(adminUser, adminPassword);
|
|
||||||
|
|
||||||
if (createResult.Succeeded)
|
|
||||||
{
|
|
||||||
await userManager.AddToRoleAsync(adminUser, "Admin");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (normalUser == null)
|
|
||||||
{
|
|
||||||
normalUser = new ApplicationUser
|
|
||||||
{
|
|
||||||
UserName = normalUsername,
|
|
||||||
EmailConfirmed = true
|
|
||||||
};
|
|
||||||
var createResult = await userManager.CreateAsync(normalUser, adminPassword);
|
|
||||||
|
|
||||||
if (createResult.Succeeded)
|
|
||||||
{
|
|
||||||
await userManager.AddToRoleAsync(adminUser, "User");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!await userManager.IsInRoleAsync(normalUser, "User"))
|
|
||||||
{
|
|
||||||
await userManager.AddToRoleAsync(normalUser, "User");
|
|
||||||
}
|
|
||||||
else if (!await userManager.IsInRoleAsync(adminUser, "Admin"))
|
|
||||||
{
|
|
||||||
await userManager.AddToRoleAsync(adminUser, "Admin");
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaType mediaType = new()
|
|
||||||
{
|
|
||||||
Name = "Movie"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!CouchLogDB.MediaType.Any())
|
|
||||||
CouchLogDB.MediaType.Add(mediaType);
|
|
||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
|
|
||||||
GlobalEntity globalEntity = new()
|
|
||||||
{
|
|
||||||
Title = "Inception",
|
|
||||||
CreationTime = DateTime.Now,
|
|
||||||
CreatorId = (await userManager.FindByNameAsync("Admin"))!.Id,
|
|
||||||
TypeId = 1,
|
|
||||||
PicturePath = "Pictures/Inception.jpg"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!CouchLogDB.GlobalEntities.Any())
|
|
||||||
CouchLogDB.GlobalEntities.Add(globalEntity);
|
|
||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
|
|
||||||
OnStartUp onStartUp = new(CouchLogDB);
|
|
||||||
onStartUp.AddBasicDatabaseEntries();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@@ -6,6 +6,13 @@
|
|||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
},
|
||||||
|
"Console": {
|
||||||
|
"FormatterName": "simple",
|
||||||
|
"FormatterOptions": {
|
||||||
|
"TimestampFormat": "[HH:mm:ss]",
|
||||||
|
"SingleLine": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*"
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
html, body {
|
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
background: #2d2d2d;
|
|
||||||
color: white
|
|
||||||
}
|
|
||||||
|
|
||||||
a, .btn-link {
|
|
||||||
color: #006bb7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-primary {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #1b6ec2;
|
|
||||||
border-color: #1861ac;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
|
||||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
padding-top: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.valid.modified:not([type=checkbox]) {
|
|
||||||
outline: 1px solid #26b050;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invalid {
|
|
||||||
outline: 1px solid #e50000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.validation-message {
|
|
||||||
color: #e50000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blazor-error-boundary {
|
|
||||||
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
|
|
||||||
padding: 1rem 1rem 1rem 3.7rem;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blazor-error-boundary::after {
|
|
||||||
content: "An error has occurred."
|
|
||||||
}
|
|
||||||
|
|
||||||
.darker-border-checkbox.form-check-input {
|
|
||||||
border-color: #929292;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
|
|
||||||
color: var(--bs-secondary-color);
|
|
||||||
text-align: end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,597 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2024 The Bootstrap Authors
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
:root,
|
|
||||||
[data-bs-theme=light] {
|
|
||||||
--bs-blue: #0d6efd;
|
|
||||||
--bs-indigo: #6610f2;
|
|
||||||
--bs-purple: #6f42c1;
|
|
||||||
--bs-pink: #d63384;
|
|
||||||
--bs-red: #dc3545;
|
|
||||||
--bs-orange: #fd7e14;
|
|
||||||
--bs-yellow: #ffc107;
|
|
||||||
--bs-green: #198754;
|
|
||||||
--bs-teal: #20c997;
|
|
||||||
--bs-cyan: #0dcaf0;
|
|
||||||
--bs-black: #000;
|
|
||||||
--bs-white: #fff;
|
|
||||||
--bs-gray: #6c757d;
|
|
||||||
--bs-gray-dark: #343a40;
|
|
||||||
--bs-gray-100: #f8f9fa;
|
|
||||||
--bs-gray-200: #e9ecef;
|
|
||||||
--bs-gray-300: #dee2e6;
|
|
||||||
--bs-gray-400: #ced4da;
|
|
||||||
--bs-gray-500: #adb5bd;
|
|
||||||
--bs-gray-600: #6c757d;
|
|
||||||
--bs-gray-700: #495057;
|
|
||||||
--bs-gray-800: #343a40;
|
|
||||||
--bs-gray-900: #212529;
|
|
||||||
--bs-primary: #0d6efd;
|
|
||||||
--bs-secondary: #6c757d;
|
|
||||||
--bs-success: #198754;
|
|
||||||
--bs-info: #0dcaf0;
|
|
||||||
--bs-warning: #ffc107;
|
|
||||||
--bs-danger: #dc3545;
|
|
||||||
--bs-light: #f8f9fa;
|
|
||||||
--bs-dark: #212529;
|
|
||||||
--bs-primary-rgb: 13, 110, 253;
|
|
||||||
--bs-secondary-rgb: 108, 117, 125;
|
|
||||||
--bs-success-rgb: 25, 135, 84;
|
|
||||||
--bs-info-rgb: 13, 202, 240;
|
|
||||||
--bs-warning-rgb: 255, 193, 7;
|
|
||||||
--bs-danger-rgb: 220, 53, 69;
|
|
||||||
--bs-light-rgb: 248, 249, 250;
|
|
||||||
--bs-dark-rgb: 33, 37, 41;
|
|
||||||
--bs-primary-text-emphasis: #052c65;
|
|
||||||
--bs-secondary-text-emphasis: #2b2f32;
|
|
||||||
--bs-success-text-emphasis: #0a3622;
|
|
||||||
--bs-info-text-emphasis: #055160;
|
|
||||||
--bs-warning-text-emphasis: #664d03;
|
|
||||||
--bs-danger-text-emphasis: #58151c;
|
|
||||||
--bs-light-text-emphasis: #495057;
|
|
||||||
--bs-dark-text-emphasis: #495057;
|
|
||||||
--bs-primary-bg-subtle: #cfe2ff;
|
|
||||||
--bs-secondary-bg-subtle: #e2e3e5;
|
|
||||||
--bs-success-bg-subtle: #d1e7dd;
|
|
||||||
--bs-info-bg-subtle: #cff4fc;
|
|
||||||
--bs-warning-bg-subtle: #fff3cd;
|
|
||||||
--bs-danger-bg-subtle: #f8d7da;
|
|
||||||
--bs-light-bg-subtle: #fcfcfd;
|
|
||||||
--bs-dark-bg-subtle: #ced4da;
|
|
||||||
--bs-primary-border-subtle: #9ec5fe;
|
|
||||||
--bs-secondary-border-subtle: #c4c8cb;
|
|
||||||
--bs-success-border-subtle: #a3cfbb;
|
|
||||||
--bs-info-border-subtle: #9eeaf9;
|
|
||||||
--bs-warning-border-subtle: #ffe69c;
|
|
||||||
--bs-danger-border-subtle: #f1aeb5;
|
|
||||||
--bs-light-border-subtle: #e9ecef;
|
|
||||||
--bs-dark-border-subtle: #adb5bd;
|
|
||||||
--bs-white-rgb: 255, 255, 255;
|
|
||||||
--bs-black-rgb: 0, 0, 0;
|
|
||||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
||||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
||||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
|
||||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
|
||||||
--bs-body-font-size: 1rem;
|
|
||||||
--bs-body-font-weight: 400;
|
|
||||||
--bs-body-line-height: 1.5;
|
|
||||||
--bs-body-color: #212529;
|
|
||||||
--bs-body-color-rgb: 33, 37, 41;
|
|
||||||
--bs-body-bg: #fff;
|
|
||||||
--bs-body-bg-rgb: 255, 255, 255;
|
|
||||||
--bs-emphasis-color: #000;
|
|
||||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
|
||||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-secondary-bg: #e9ecef;
|
|
||||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
|
||||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-tertiary-bg: #f8f9fa;
|
|
||||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #0d6efd;
|
|
||||||
--bs-link-color-rgb: 13, 110, 253;
|
|
||||||
--bs-link-decoration: underline;
|
|
||||||
--bs-link-hover-color: #0a58ca;
|
|
||||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
|
||||||
--bs-code-color: #d63384;
|
|
||||||
--bs-highlight-color: #212529;
|
|
||||||
--bs-highlight-bg: #fff3cd;
|
|
||||||
--bs-border-width: 1px;
|
|
||||||
--bs-border-style: solid;
|
|
||||||
--bs-border-color: #dee2e6;
|
|
||||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-border-radius: 0.375rem;
|
|
||||||
--bs-border-radius-sm: 0.25rem;
|
|
||||||
--bs-border-radius-lg: 0.5rem;
|
|
||||||
--bs-border-radius-xl: 1rem;
|
|
||||||
--bs-border-radius-xxl: 2rem;
|
|
||||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
|
||||||
--bs-border-radius-pill: 50rem;
|
|
||||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
||||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-focus-ring-width: 0.25rem;
|
|
||||||
--bs-focus-ring-opacity: 0.25;
|
|
||||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
|
||||||
--bs-form-valid-color: #198754;
|
|
||||||
--bs-form-valid-border-color: #198754;
|
|
||||||
--bs-form-invalid-color: #dc3545;
|
|
||||||
--bs-form-invalid-border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-bs-theme=dark] {
|
|
||||||
color-scheme: dark;
|
|
||||||
--bs-body-color: #dee2e6;
|
|
||||||
--bs-body-color-rgb: 222, 226, 230;
|
|
||||||
--bs-body-bg: #212529;
|
|
||||||
--bs-body-bg-rgb: 33, 37, 41;
|
|
||||||
--bs-emphasis-color: #fff;
|
|
||||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
|
||||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-secondary-bg: #343a40;
|
|
||||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
|
||||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-tertiary-bg: #2b3035;
|
|
||||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
|
||||||
--bs-primary-text-emphasis: #6ea8fe;
|
|
||||||
--bs-secondary-text-emphasis: #a7acb1;
|
|
||||||
--bs-success-text-emphasis: #75b798;
|
|
||||||
--bs-info-text-emphasis: #6edff6;
|
|
||||||
--bs-warning-text-emphasis: #ffda6a;
|
|
||||||
--bs-danger-text-emphasis: #ea868f;
|
|
||||||
--bs-light-text-emphasis: #f8f9fa;
|
|
||||||
--bs-dark-text-emphasis: #dee2e6;
|
|
||||||
--bs-primary-bg-subtle: #031633;
|
|
||||||
--bs-secondary-bg-subtle: #161719;
|
|
||||||
--bs-success-bg-subtle: #051b11;
|
|
||||||
--bs-info-bg-subtle: #032830;
|
|
||||||
--bs-warning-bg-subtle: #332701;
|
|
||||||
--bs-danger-bg-subtle: #2c0b0e;
|
|
||||||
--bs-light-bg-subtle: #343a40;
|
|
||||||
--bs-dark-bg-subtle: #1a1d20;
|
|
||||||
--bs-primary-border-subtle: #084298;
|
|
||||||
--bs-secondary-border-subtle: #41464b;
|
|
||||||
--bs-success-border-subtle: #0f5132;
|
|
||||||
--bs-info-border-subtle: #087990;
|
|
||||||
--bs-warning-border-subtle: #997404;
|
|
||||||
--bs-danger-border-subtle: #842029;
|
|
||||||
--bs-light-border-subtle: #495057;
|
|
||||||
--bs-dark-border-subtle: #343a40;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #6ea8fe;
|
|
||||||
--bs-link-hover-color: #8bb9fe;
|
|
||||||
--bs-link-color-rgb: 110, 168, 254;
|
|
||||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
|
||||||
--bs-code-color: #e685b5;
|
|
||||||
--bs-highlight-color: #dee2e6;
|
|
||||||
--bs-highlight-bg: #664d03;
|
|
||||||
--bs-border-color: #495057;
|
|
||||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
|
||||||
--bs-form-valid-color: #75b798;
|
|
||||||
--bs-form-valid-border-color: #75b798;
|
|
||||||
--bs-form-invalid-color: #ea868f;
|
|
||||||
--bs-form-invalid-border-color: #ea868f;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
|
||||||
*::before,
|
|
||||||
*::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
:root {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: var(--bs-body-font-family);
|
|
||||||
font-size: var(--bs-body-font-size);
|
|
||||||
font-weight: var(--bs-body-font-weight);
|
|
||||||
line-height: var(--bs-body-line-height);
|
|
||||||
color: var(--bs-body-color);
|
|
||||||
text-align: var(--bs-body-text-align);
|
|
||||||
background-color: var(--bs-body-bg);
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
margin: 1rem 0;
|
|
||||||
color: inherit;
|
|
||||||
border: 0;
|
|
||||||
border-top: var(--bs-border-width) solid;
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6, h5, h4, h3, h2, h1 {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.2;
|
|
||||||
color: var(--bs-heading-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: calc(1.375rem + 1.5vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: calc(1.325rem + 0.9vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h2 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: calc(1.3rem + 0.6vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h3 {
|
|
||||||
font-size: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h4 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6 {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
abbr[title] {
|
|
||||||
-webkit-text-decoration: underline dotted;
|
|
||||||
text-decoration: underline dotted;
|
|
||||||
cursor: help;
|
|
||||||
-webkit-text-decoration-skip-ink: none;
|
|
||||||
text-decoration-skip-ink: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
address {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-style: normal;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul {
|
|
||||||
padding-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul,
|
|
||||||
dl {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol ol,
|
|
||||||
ul ul,
|
|
||||||
ol ul,
|
|
||||||
ul ol {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
b,
|
|
||||||
strong {
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
small {
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark {
|
|
||||||
padding: 0.1875em;
|
|
||||||
color: var(--bs-highlight-color);
|
|
||||||
background-color: var(--bs-highlight-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub,
|
|
||||||
sup {
|
|
||||||
position: relative;
|
|
||||||
font-size: 0.75em;
|
|
||||||
line-height: 0;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub {
|
|
||||||
bottom: -0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup {
|
|
||||||
top: -0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre,
|
|
||||||
code,
|
|
||||||
kbd,
|
|
||||||
samp {
|
|
||||||
font-family: var(--bs-font-monospace);
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
display: block;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
overflow: auto;
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
pre code {
|
|
||||||
font-size: inherit;
|
|
||||||
color: inherit;
|
|
||||||
word-break: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-code-color);
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
a > code {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
kbd {
|
|
||||||
padding: 0.1875rem 0.375rem;
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-body-bg);
|
|
||||||
background-color: var(--bs-body-color);
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
kbd kbd {
|
|
||||||
padding: 0;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
img,
|
|
||||||
svg {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
caption-side: bottom;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
caption {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
color: var(--bs-secondary-color);
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: inherit;
|
|
||||||
text-align: -webkit-match-parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead,
|
|
||||||
tbody,
|
|
||||||
tfoot,
|
|
||||||
tr,
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-color: inherit;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:focus:not(:focus-visible) {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button,
|
|
||||||
select,
|
|
||||||
optgroup,
|
|
||||||
textarea {
|
|
||||||
margin: 0;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
select {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
[role=button] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
word-wrap: normal;
|
|
||||||
}
|
|
||||||
select:disabled {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
[type=button],
|
|
||||||
[type=reset],
|
|
||||||
[type=submit] {
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
button:not(:disabled),
|
|
||||||
[type=button]:not(:disabled),
|
|
||||||
[type=reset]:not(:disabled),
|
|
||||||
[type=submit]:not(:disabled) {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-moz-focus-inner {
|
|
||||||
padding: 0;
|
|
||||||
border-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldset {
|
|
||||||
min-width: 0;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
legend {
|
|
||||||
float: left;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
legend {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
legend + * {
|
|
||||||
clear: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-datetime-edit-fields-wrapper,
|
|
||||||
::-webkit-datetime-edit-text,
|
|
||||||
::-webkit-datetime-edit-minute,
|
|
||||||
::-webkit-datetime-edit-hour-field,
|
|
||||||
::-webkit-datetime-edit-day-field,
|
|
||||||
::-webkit-datetime-edit-month-field,
|
|
||||||
::-webkit-datetime-edit-year-field {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-inner-spin-button {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type=search] {
|
|
||||||
-webkit-appearance: textfield;
|
|
||||||
outline-offset: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rtl:raw:
|
|
||||||
[type="tel"],
|
|
||||||
[type="url"],
|
|
||||||
[type="email"],
|
|
||||||
[type="number"] {
|
|
||||||
direction: ltr;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
::-webkit-search-decoration {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-color-swatch-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-file-upload-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
::file-selector-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
output {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
summary {
|
|
||||||
display: list-item;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress {
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
[hidden] {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,594 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2024 The Bootstrap Authors
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
:root,
|
|
||||||
[data-bs-theme=light] {
|
|
||||||
--bs-blue: #0d6efd;
|
|
||||||
--bs-indigo: #6610f2;
|
|
||||||
--bs-purple: #6f42c1;
|
|
||||||
--bs-pink: #d63384;
|
|
||||||
--bs-red: #dc3545;
|
|
||||||
--bs-orange: #fd7e14;
|
|
||||||
--bs-yellow: #ffc107;
|
|
||||||
--bs-green: #198754;
|
|
||||||
--bs-teal: #20c997;
|
|
||||||
--bs-cyan: #0dcaf0;
|
|
||||||
--bs-black: #000;
|
|
||||||
--bs-white: #fff;
|
|
||||||
--bs-gray: #6c757d;
|
|
||||||
--bs-gray-dark: #343a40;
|
|
||||||
--bs-gray-100: #f8f9fa;
|
|
||||||
--bs-gray-200: #e9ecef;
|
|
||||||
--bs-gray-300: #dee2e6;
|
|
||||||
--bs-gray-400: #ced4da;
|
|
||||||
--bs-gray-500: #adb5bd;
|
|
||||||
--bs-gray-600: #6c757d;
|
|
||||||
--bs-gray-700: #495057;
|
|
||||||
--bs-gray-800: #343a40;
|
|
||||||
--bs-gray-900: #212529;
|
|
||||||
--bs-primary: #0d6efd;
|
|
||||||
--bs-secondary: #6c757d;
|
|
||||||
--bs-success: #198754;
|
|
||||||
--bs-info: #0dcaf0;
|
|
||||||
--bs-warning: #ffc107;
|
|
||||||
--bs-danger: #dc3545;
|
|
||||||
--bs-light: #f8f9fa;
|
|
||||||
--bs-dark: #212529;
|
|
||||||
--bs-primary-rgb: 13, 110, 253;
|
|
||||||
--bs-secondary-rgb: 108, 117, 125;
|
|
||||||
--bs-success-rgb: 25, 135, 84;
|
|
||||||
--bs-info-rgb: 13, 202, 240;
|
|
||||||
--bs-warning-rgb: 255, 193, 7;
|
|
||||||
--bs-danger-rgb: 220, 53, 69;
|
|
||||||
--bs-light-rgb: 248, 249, 250;
|
|
||||||
--bs-dark-rgb: 33, 37, 41;
|
|
||||||
--bs-primary-text-emphasis: #052c65;
|
|
||||||
--bs-secondary-text-emphasis: #2b2f32;
|
|
||||||
--bs-success-text-emphasis: #0a3622;
|
|
||||||
--bs-info-text-emphasis: #055160;
|
|
||||||
--bs-warning-text-emphasis: #664d03;
|
|
||||||
--bs-danger-text-emphasis: #58151c;
|
|
||||||
--bs-light-text-emphasis: #495057;
|
|
||||||
--bs-dark-text-emphasis: #495057;
|
|
||||||
--bs-primary-bg-subtle: #cfe2ff;
|
|
||||||
--bs-secondary-bg-subtle: #e2e3e5;
|
|
||||||
--bs-success-bg-subtle: #d1e7dd;
|
|
||||||
--bs-info-bg-subtle: #cff4fc;
|
|
||||||
--bs-warning-bg-subtle: #fff3cd;
|
|
||||||
--bs-danger-bg-subtle: #f8d7da;
|
|
||||||
--bs-light-bg-subtle: #fcfcfd;
|
|
||||||
--bs-dark-bg-subtle: #ced4da;
|
|
||||||
--bs-primary-border-subtle: #9ec5fe;
|
|
||||||
--bs-secondary-border-subtle: #c4c8cb;
|
|
||||||
--bs-success-border-subtle: #a3cfbb;
|
|
||||||
--bs-info-border-subtle: #9eeaf9;
|
|
||||||
--bs-warning-border-subtle: #ffe69c;
|
|
||||||
--bs-danger-border-subtle: #f1aeb5;
|
|
||||||
--bs-light-border-subtle: #e9ecef;
|
|
||||||
--bs-dark-border-subtle: #adb5bd;
|
|
||||||
--bs-white-rgb: 255, 255, 255;
|
|
||||||
--bs-black-rgb: 0, 0, 0;
|
|
||||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
||||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
||||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
|
||||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
|
||||||
--bs-body-font-size: 1rem;
|
|
||||||
--bs-body-font-weight: 400;
|
|
||||||
--bs-body-line-height: 1.5;
|
|
||||||
--bs-body-color: #212529;
|
|
||||||
--bs-body-color-rgb: 33, 37, 41;
|
|
||||||
--bs-body-bg: #fff;
|
|
||||||
--bs-body-bg-rgb: 255, 255, 255;
|
|
||||||
--bs-emphasis-color: #000;
|
|
||||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
|
||||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-secondary-bg: #e9ecef;
|
|
||||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
|
||||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-tertiary-bg: #f8f9fa;
|
|
||||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #0d6efd;
|
|
||||||
--bs-link-color-rgb: 13, 110, 253;
|
|
||||||
--bs-link-decoration: underline;
|
|
||||||
--bs-link-hover-color: #0a58ca;
|
|
||||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
|
||||||
--bs-code-color: #d63384;
|
|
||||||
--bs-highlight-color: #212529;
|
|
||||||
--bs-highlight-bg: #fff3cd;
|
|
||||||
--bs-border-width: 1px;
|
|
||||||
--bs-border-style: solid;
|
|
||||||
--bs-border-color: #dee2e6;
|
|
||||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-border-radius: 0.375rem;
|
|
||||||
--bs-border-radius-sm: 0.25rem;
|
|
||||||
--bs-border-radius-lg: 0.5rem;
|
|
||||||
--bs-border-radius-xl: 1rem;
|
|
||||||
--bs-border-radius-xxl: 2rem;
|
|
||||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
|
||||||
--bs-border-radius-pill: 50rem;
|
|
||||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
||||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-focus-ring-width: 0.25rem;
|
|
||||||
--bs-focus-ring-opacity: 0.25;
|
|
||||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
|
||||||
--bs-form-valid-color: #198754;
|
|
||||||
--bs-form-valid-border-color: #198754;
|
|
||||||
--bs-form-invalid-color: #dc3545;
|
|
||||||
--bs-form-invalid-border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-bs-theme=dark] {
|
|
||||||
color-scheme: dark;
|
|
||||||
--bs-body-color: #dee2e6;
|
|
||||||
--bs-body-color-rgb: 222, 226, 230;
|
|
||||||
--bs-body-bg: #212529;
|
|
||||||
--bs-body-bg-rgb: 33, 37, 41;
|
|
||||||
--bs-emphasis-color: #fff;
|
|
||||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
|
||||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-secondary-bg: #343a40;
|
|
||||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
|
||||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-tertiary-bg: #2b3035;
|
|
||||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
|
||||||
--bs-primary-text-emphasis: #6ea8fe;
|
|
||||||
--bs-secondary-text-emphasis: #a7acb1;
|
|
||||||
--bs-success-text-emphasis: #75b798;
|
|
||||||
--bs-info-text-emphasis: #6edff6;
|
|
||||||
--bs-warning-text-emphasis: #ffda6a;
|
|
||||||
--bs-danger-text-emphasis: #ea868f;
|
|
||||||
--bs-light-text-emphasis: #f8f9fa;
|
|
||||||
--bs-dark-text-emphasis: #dee2e6;
|
|
||||||
--bs-primary-bg-subtle: #031633;
|
|
||||||
--bs-secondary-bg-subtle: #161719;
|
|
||||||
--bs-success-bg-subtle: #051b11;
|
|
||||||
--bs-info-bg-subtle: #032830;
|
|
||||||
--bs-warning-bg-subtle: #332701;
|
|
||||||
--bs-danger-bg-subtle: #2c0b0e;
|
|
||||||
--bs-light-bg-subtle: #343a40;
|
|
||||||
--bs-dark-bg-subtle: #1a1d20;
|
|
||||||
--bs-primary-border-subtle: #084298;
|
|
||||||
--bs-secondary-border-subtle: #41464b;
|
|
||||||
--bs-success-border-subtle: #0f5132;
|
|
||||||
--bs-info-border-subtle: #087990;
|
|
||||||
--bs-warning-border-subtle: #997404;
|
|
||||||
--bs-danger-border-subtle: #842029;
|
|
||||||
--bs-light-border-subtle: #495057;
|
|
||||||
--bs-dark-border-subtle: #343a40;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #6ea8fe;
|
|
||||||
--bs-link-hover-color: #8bb9fe;
|
|
||||||
--bs-link-color-rgb: 110, 168, 254;
|
|
||||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
|
||||||
--bs-code-color: #e685b5;
|
|
||||||
--bs-highlight-color: #dee2e6;
|
|
||||||
--bs-highlight-bg: #664d03;
|
|
||||||
--bs-border-color: #495057;
|
|
||||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
|
||||||
--bs-form-valid-color: #75b798;
|
|
||||||
--bs-form-valid-border-color: #75b798;
|
|
||||||
--bs-form-invalid-color: #ea868f;
|
|
||||||
--bs-form-invalid-border-color: #ea868f;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
|
||||||
*::before,
|
|
||||||
*::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
:root {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: var(--bs-body-font-family);
|
|
||||||
font-size: var(--bs-body-font-size);
|
|
||||||
font-weight: var(--bs-body-font-weight);
|
|
||||||
line-height: var(--bs-body-line-height);
|
|
||||||
color: var(--bs-body-color);
|
|
||||||
text-align: var(--bs-body-text-align);
|
|
||||||
background-color: var(--bs-body-bg);
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
margin: 1rem 0;
|
|
||||||
color: inherit;
|
|
||||||
border: 0;
|
|
||||||
border-top: var(--bs-border-width) solid;
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6, h5, h4, h3, h2, h1 {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.2;
|
|
||||||
color: var(--bs-heading-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: calc(1.375rem + 1.5vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: calc(1.325rem + 0.9vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h2 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: calc(1.3rem + 0.6vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h3 {
|
|
||||||
font-size: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h4 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6 {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
abbr[title] {
|
|
||||||
-webkit-text-decoration: underline dotted;
|
|
||||||
text-decoration: underline dotted;
|
|
||||||
cursor: help;
|
|
||||||
-webkit-text-decoration-skip-ink: none;
|
|
||||||
text-decoration-skip-ink: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
address {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-style: normal;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul {
|
|
||||||
padding-right: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul,
|
|
||||||
dl {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol ol,
|
|
||||||
ul ul,
|
|
||||||
ol ul,
|
|
||||||
ul ol {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
b,
|
|
||||||
strong {
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
small {
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark {
|
|
||||||
padding: 0.1875em;
|
|
||||||
color: var(--bs-highlight-color);
|
|
||||||
background-color: var(--bs-highlight-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub,
|
|
||||||
sup {
|
|
||||||
position: relative;
|
|
||||||
font-size: 0.75em;
|
|
||||||
line-height: 0;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub {
|
|
||||||
bottom: -0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup {
|
|
||||||
top: -0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre,
|
|
||||||
code,
|
|
||||||
kbd,
|
|
||||||
samp {
|
|
||||||
font-family: var(--bs-font-monospace);
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
display: block;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
overflow: auto;
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
pre code {
|
|
||||||
font-size: inherit;
|
|
||||||
color: inherit;
|
|
||||||
word-break: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-code-color);
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
a > code {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
kbd {
|
|
||||||
padding: 0.1875rem 0.375rem;
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-body-bg);
|
|
||||||
background-color: var(--bs-body-color);
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
kbd kbd {
|
|
||||||
padding: 0;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
img,
|
|
||||||
svg {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
caption-side: bottom;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
caption {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
color: var(--bs-secondary-color);
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: inherit;
|
|
||||||
text-align: -webkit-match-parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead,
|
|
||||||
tbody,
|
|
||||||
tfoot,
|
|
||||||
tr,
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-color: inherit;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:focus:not(:focus-visible) {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button,
|
|
||||||
select,
|
|
||||||
optgroup,
|
|
||||||
textarea {
|
|
||||||
margin: 0;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
select {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
[role=button] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
word-wrap: normal;
|
|
||||||
}
|
|
||||||
select:disabled {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
[type=button],
|
|
||||||
[type=reset],
|
|
||||||
[type=submit] {
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
button:not(:disabled),
|
|
||||||
[type=button]:not(:disabled),
|
|
||||||
[type=reset]:not(:disabled),
|
|
||||||
[type=submit]:not(:disabled) {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-moz-focus-inner {
|
|
||||||
padding: 0;
|
|
||||||
border-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldset {
|
|
||||||
min-width: 0;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
legend {
|
|
||||||
float: right;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
legend {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
legend + * {
|
|
||||||
clear: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-datetime-edit-fields-wrapper,
|
|
||||||
::-webkit-datetime-edit-text,
|
|
||||||
::-webkit-datetime-edit-minute,
|
|
||||||
::-webkit-datetime-edit-hour-field,
|
|
||||||
::-webkit-datetime-edit-day-field,
|
|
||||||
::-webkit-datetime-edit-month-field,
|
|
||||||
::-webkit-datetime-edit-year-field {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-inner-spin-button {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type=search] {
|
|
||||||
-webkit-appearance: textfield;
|
|
||||||
outline-offset: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type="tel"],
|
|
||||||
[type="url"],
|
|
||||||
[type="email"],
|
|
||||||
[type="number"] {
|
|
||||||
direction: ltr;
|
|
||||||
}
|
|
||||||
::-webkit-search-decoration {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-color-swatch-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-file-upload-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
::file-selector-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
output {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
summary {
|
|
||||||
display: list-item;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress {
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
[hidden] {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-12057
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-12030
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-4447
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-4494
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,8 +0,0 @@
|
|||||||
window.initializeBootstrapCollapse = () => {
|
|
||||||
var collapseElementList = [].slice.call(document.querySelectorAll('[data-bs-toggle="collapse"]'))
|
|
||||||
var collapseList = collapseElementList.map(function (collapseEl) {
|
|
||||||
return new bootstrap.Collapse(document.querySelector(collapseEl.dataset.bsTarget), {
|
|
||||||
toggle: false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
};
|
|
||||||
@@ -1,2 +1,10 @@
|
|||||||
# Watchlog
|
# Watchlog
|
||||||
## Work in Progress
|
## Information
|
||||||
|
- This Repo has a Mirror on Codeberg, but the Releases a only available on [Gitea](https://gitea.penry.de/Penry/CouchLog) for now
|
||||||
|
|
||||||
|
## About docker image Releases
|
||||||
|
There are two options:
|
||||||
|
- latest: Is the latest release Version
|
||||||
|
- nightly: Is the latest commit on the main branch
|
||||||
|
|
||||||
|
Test-Commit
|
||||||
|
|||||||
Reference in New Issue
Block a user