Merge branch 'main' into Subscriptions

This commit is contained in:
Marcel Baumgartner
2023-04-04 01:24:50 +02:00
committed by GitHub
30 changed files with 578 additions and 216 deletions

View File

@@ -3,6 +3,7 @@
@using Moonlight.App.Repositories
@using Newtonsoft.Json
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Log
@inject UserRepository UserRepository
@@ -18,7 +19,7 @@
<div class="fs-5 fw-semibold mb-2">
@if (User == null)
{
<TL>Password change for</TL> @(Data[0])
<TL>Password change for</TL> @(Data[0].Value)
}
else
{
@@ -38,18 +39,18 @@
public AuditLogEntry Entry { get; set; }
private User? User;
private string[] Data;
private LogData[] Data;
protected override void OnInitialized()
{
Data = JsonConvert.DeserializeObject<string[]>(Entry.JsonData)!;
Data = JsonConvert.DeserializeObject<LogData[]>(Entry.JsonData)!;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
User = UserRepository.Get().FirstOrDefault(x => x.Email == Data[0]);
User = UserRepository.Get().FirstOrDefault(x => x.Email == Data[0].Value);
await InvokeAsync(StateHasChanged);
}

View File

@@ -2,6 +2,7 @@
@using Moonlight.App.Helpers
@using Newtonsoft.Json
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Log
@using Moonlight.App.Repositories.Servers
@inject ServerRepository ServerRepository
@@ -18,11 +19,11 @@
<div class="fs-5 fw-semibold mb-2">
@if (Server == null)
{
<TL>Change power state for</TL> @(Data[0]) <TL>to</TL> @(Data[1])
<TL>Change power state for</TL> @(Data[0].Value) <TL>to</TL> @(Data[1].Value)
}
else
{
<TL>Change power state for</TL> <a href="/admin/servers/edit/@(Server.Id)">@(Server.Name)</a> <TL>to</TL> @(Data[1])
<TL>Change power state for</TL> <a href="/admin/servers/edit/@(Server.Id)">@(Server.Name)</a> <TL>to</TL> @(Data[1].Value)
}
</div>
<div class="d-flex align-items-center mt-1 fs-6">
@@ -38,18 +39,18 @@
public AuditLogEntry Entry { get; set; }
private Server? Server;
private string[] Data;
private LogData[] Data;
protected override void OnInitialized()
{
Data = JsonConvert.DeserializeObject<string[]>(Entry.JsonData)!;
Data = JsonConvert.DeserializeObject<LogData[]>(Entry.JsonData)!;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
Server = ServerRepository.Get().FirstOrDefault(x => x.Uuid == Guid.Parse(Data[0]));
Server = ServerRepository.Get().FirstOrDefault(x => x.Uuid == Guid.Parse(Data[0].Value));
await InvokeAsync(StateHasChanged);
}

View File

@@ -3,6 +3,7 @@
@using Moonlight.App.Repositories
@using Newtonsoft.Json
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Log
@inject UserRepository UserRepository
@@ -18,7 +19,7 @@
<div class="fs-5 fw-semibold mb-2">
@if (User == null)
{
<TL>New login for</TL> @(Data[0])
<TL>New login for</TL> @(Data[0].Value)
}
else
{
@@ -38,18 +39,18 @@
public AuditLogEntry Entry { get; set; }
private User? User;
private string[] Data;
private LogData[] Data;
protected override void OnInitialized()
{
Data = JsonConvert.DeserializeObject<string[]>(Entry.JsonData)!;
Data = JsonConvert.DeserializeObject<LogData[]>(Entry.JsonData)!;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
User = UserRepository.Get().FirstOrDefault(x => x.Email == Data[0]);
User = UserRepository.Get().FirstOrDefault(x => x.Email == Data[0].Value);
await InvokeAsync(StateHasChanged);
}

View File

@@ -3,6 +3,7 @@
@using Moonlight.App.Repositories
@using Newtonsoft.Json
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Log
@inject UserRepository UserRepository
@@ -18,7 +19,7 @@
<div class="fs-5 fw-semibold mb-2">
@if (User == null)
{
<TL>Register for</TL> @(Data[0])
<TL>Register for</TL> @(Data[0].Value)
}
else
{
@@ -38,18 +39,18 @@
public AuditLogEntry Entry { get; set; }
private User? User;
private string[] Data;
private LogData[] Data;
protected override void OnInitialized()
{
Data = JsonConvert.DeserializeObject<string[]>(Entry.JsonData)!;
Data = JsonConvert.DeserializeObject<LogData[]>(Entry.JsonData)!;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
User = UserRepository.Get().FirstOrDefault(x => x.Email == Data[0]);
User = UserRepository.Get().FirstOrDefault(x => x.Email == Data[0].Value);
await InvokeAsync(StateHasChanged);
}

View File

@@ -0,0 +1,64 @@
@using Moonlight.App.Services
@using Moonlight.App.Models.Forms
@using Moonlight.App.Services.Sessions
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Misc
@using Moonlight.App.Repositories
@inject SmartTranslateService SmartTranslateService
@inject IdentityService IdentityService
@inject UserService UserService
@inject UserRepository UserRepository
@inject NavigationManager NavigationManager
<div class="d-flex flex-center">
<div class="card rounded-3 w-md-550px">
<div class="card-body">
<div class="d-flex flex-center flex-column-fluid">
<LazyLoader Load="Load">
<SmartForm Model="Password" OnValidSubmit="DoChange">
<div class="text-center mt-3 mb-11">
<h1 class="text-dark fw-bolder mb-3">
<TL>Change your password</TL>
</h1>
<div class="text-gray-500 fw-semibold fs-6">
<TL>You need to change your password in order to use moonlight</TL>
</div>
</div>
<div class="row g-3 mb-9">
<div class="col-md-9">
<InputText @bind-Value="Password.Password" type="password" placeholder="@(SmartTranslateService.Translate("New password"))" class="form-control bg-transparent"/>
</div>
<div class="col">
<button type="submit" class="btn btn-primary float-end">
<TL>Change</TL>
</button>
</div>
</div>
</SmartForm>
</LazyLoader>
</div>
</div>
</div>
</div>
@code {
private PasswordModel Password = new();
private User User;
private async Task Load(LazyLoader loader)
{
User = await IdentityService.Get();
}
private async Task DoChange()
{
await UserService.ChangePassword(User, Password.Password);
User.Status = UserStatus.Unverified;
UserRepository.Update(User);
NavigationManager.NavigateTo(NavigationManager.Uri, true);
}
}

View File

@@ -0,0 +1,67 @@
@using Microsoft.AspNetCore.Components
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Forms
@using Moonlight.App.Models.Misc
@using Moonlight.App.Repositories
@using Moonlight.App.Services
@using Moonlight.App.Services.Sessions
@inject IdentityService IdentityService
@inject UserRepository UserRepository
@inject SmartTranslateService SmartTranslateService
@inject NavigationManager NavigationManager
<div class="d-flex flex-center">
<div class="card rounded-3 w-md-550px">
<div class="card-body">
<div class="d-flex flex-center flex-column-fluid">
<LazyLoader Load="Load">
<SmartForm Model="Name" OnValidSubmit="SetName">
<div class="text-center mt-3 mb-11">
<h1 class="text-dark fw-bolder mb-3">
<TL>Enter your information</TL>
</h1>
<div class="text-gray-500 fw-semibold fs-6">
<TL>You need to enter your full name in order to use moonlight</TL>
</div>
</div>
<div class="row g-3">
<div class="col">
<InputText @bind-Value="Name.FirstName" type="text" placeholder="@(SmartTranslateService.Translate("First name"))" class="form-control bg-transparent"/>
</div>
<div class="col">
<InputText @bind-Value="Name.LastName" type="text" placeholder="@(SmartTranslateService.Translate("Last name"))" class="form-control bg-transparent"/>
</div>
</div>
<button type="submit" class="btn btn-primary float-end mt-3">
<TL>Change</TL>
</button>
</SmartForm>
</LazyLoader>
</div>
</div>
</div>
</div>
@code {
private User User;
private NameModel Name = new ();
private async Task Load(LazyLoader loader)
{
User = await IdentityService.Get();
}
private async Task SetName()
{
User.FirstName = Name.FirstName;
User.LastName = Name.LastName;
User.Status = UserStatus.Unverified;
UserRepository.Update(User);
NavigationManager.NavigateTo(NavigationManager.Uri, true);
}
}

View File

@@ -53,7 +53,7 @@ else
{
receivedExceptions.Add(exception);
await ErrorLogService.Log(exception);
await ErrorLogService.Log(exception, x => {});
await base.OnErrorAsync(exception);
}

View File

@@ -79,6 +79,14 @@
{
<DisabledAlert></DisabledAlert>
}
else if (User.Status == UserStatus.PasswordPending)
{
<PasswordChangeView></PasswordChangeView>
}
else if (User.Status == UserStatus.DataPending)
{
<UserDataSetView></UserDataSetView>
}
else
{
@Body

View File

@@ -14,45 +14,53 @@
<LazyLoader @ref="LazyLoader" Load="Load">
<div class="card">
<div class="card-body">
<div class="d-flex flex-column flex-xl-row p-7">
<div class="d-flex flex-column flex-xl-row p-5 pb-0">
<div class="flex-lg-row-fluid me-xl-15 mb-20 mb-xl-0">
<div class="mb-0">
<h1 class="text-dark mb-10">
<h1 class="text-dark mb-6">
<TL>Open tickets</TL>
</h1>
<div class="mb-10">
<div class="separator"></div>
<div class="mb-5">
@if (Users.Any())
{
foreach (var user in Users)
{
<div class="d-flex mb-10">
<span class="svg-icon svg-icon-2x me-5 ms-n1 mt-2 svg-icon-success">
<i class="text-primary bx bx-md bx-message-dots"></i>
</span>
<div class="d-flex flex-column">
<div class="d-flex align-items-center mb-2">
<a href="/admin/support/view/@(user.Id)" class="text-dark text-hover-primary fs-4 me-3 fw-semibold">
@(user.FirstName) @(user.LastName)
</a>
</div>
<span class="text-muted fw-semibold fs-6">
@{
var lastMessage = MessageCache.ContainsKey(user) ? MessageCache[user] : null;
}
@if (lastMessage == null)
{
<TL>No message sent yet</TL>
}
else
{
@(lastMessage.Message)
}
</span>
</div>
<div class="d-flex mt-3 mb-3 ms-2 me-2">
<table>
<tr>
<td rowspan="2">
<span class="svg-icon svg-icon-2x me-5 ms-n1 svg-icon-success">
<i class="text-primary bx bx-md bx-message-dots"></i>
</span>
</td>
<td>
<a href="/admin/support/view/@(user.Id)" class="text-dark text-hover-primary fs-4 me-3 fw-semibold">
@(user.FirstName) @(user.LastName)
</a>
</td>
</tr>
<tr>
<td>
<span class="text-muted fw-semibold fs-6">
@{
var lastMessage = MessageCache.ContainsKey(user) ? MessageCache[user] : null;
}
@if (lastMessage == null)
{
<TL>No message sent yet</TL>
}
else
{
@(lastMessage.Message)
}
</span>
</td>
</tr>
</table>
</div>
<div class="separator"></div>
}
}
else
@@ -64,39 +72,6 @@
</div>
</div>
</div>
<div class="flex-column flex-lg-row-auto w-100 mw-lg-300px mw-xxl-350px">
<div class="card-rounded bg-primary bg-opacity-5 p-10 mb-15">
<h2 class="text-dark fw-bold mb-11">
<TL>Actions</TL>
</h2>
<div class="d-flex align-items-center mb-10">
<!--begin::Icon-->
<i class="bi bi-file-earmark-text text-primary fs-1 me-5"></i>
<!--end::SymIconbol-->
<!--begin::Info-->
<div class="d-flex flex-column">
<h5 class="text-gray-800 fw-bold">Project Briefing</h5>
<!--begin::Section-->
<div class="fw-semibold">
<!--begin::Desc-->
<span class="text-muted">Check out our</span>
<!--end::Desc-->
<!--begin::Link-->
<a href="#" class="link-primary">Support Policy</a>
<!--end::Link-->
</div>
<!--end::Section-->
</div>
<!--end::Info-->
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -22,11 +22,11 @@
{
<div class="row">
<div class="d-flex flex-column flex-xl-row p-7">
<div class="flex-lg-row-fluid me-xl-15 mb-20 mb-xl-0">
<div class="flex-lg-row-fluid me-6 mb-20 mb-xl-0">
<div class="card">
<div class="card-body">
<LazyLoader Load="LoadMessages">
<div class="scroll-y me-n5 pe-5" style="max-height: 65vh; display: flex; flex-direction: column-reverse;">
<div class="scroll-y me-n5 pe-5" style="max-height: 55vh; display: flex; flex-direction: column-reverse;">
@foreach (var message in Messages)
{
if (message.IsSystem || message.IsSupport)
@@ -99,10 +99,10 @@
@if (typingUsers.Any())
{
<span class="mb-5 fs-5 d-flex flex-row">
<div class="wave me-3">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="wave me-1">
<div class="dot h-5px w-5px" style="margin-right: 1px;"></div>
<div class="dot h-5px w-5px" style="margin-right: 1px;"></div>
<div class="dot h-5px w-5px"></div>
</div>
@if (typingUsers.Length > 1)
{
@@ -118,52 +118,56 @@
}
</span>
}
<textarea @bind="Content" @oninput="OnTyping" class="form-control mb-3" rows="1" placeholder="Type a message">
</textarea>
<div class="d-flex flex-stack">
<div class="d-flex align-items-center me-2">
<button class="btn btn-sm btn-icon btn-active-light-primary me-1" type="button">
<i class="bx bx-upload fs-3"></i>
</button>
</div>
<WButton Text="@(SmartTranslateService.Translate("Send"))"
WorkingText="@(SmartTranslateService.Translate("Sending"))"
CssClasses="btn-primary"
OnClick="Send">
</WButton>
<table class="w-100">
<tr>
<!--<td class="align-top">
<button class="btn btn-sm btn-icon btn-active-light-primary me-1" type="button">
<i class="bx bx-upload fs-3"></i>
</button>
</td>-->
<td class="w-100">
<textarea @bind="Content" @oninput="OnTyping" class="form-control mb-3 form-control-flush" rows="1" placeholder="Type a message">
</textarea>
</td>
<td class="align-top">
<WButton Text="@(SmartTranslateService.Translate("Send"))"
WorkingText="@(SmartTranslateService.Translate("Sending"))"
CssClasses="btn-primary ms-2"
OnClick="Send">
</WButton>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="flex-column flex-lg-row-auto w-100 mw-lg-300px mw-xxl-350px">
<div class="card p-10 mb-15">
<h2 class="text-dark fw-bold mb-11">
<div class="card p-10 mb-15 pb-8">
<h2 class="text-dark fw-bold mb-2">
<TL>User information</TL>
</h2>
<div class="d-flex align-items-center mb-6">
<spna class="fw-semibold text-gray-800 fs-5 m-0">
<TL>Firstname</TL>: @(User.FirstName)
</spna>
<div class="d-flex align-items-center mb-1">
<span class="fw-semibold text-gray-800 fs-5 m-0">
<TL>Name</TL>: @(User.FirstName) @User.LastName
</span>
</div>
<div class="d-flex align-items-center mb-6">
<spna class="fw-semibold text-gray-800 fs-5 m-0">
<TL>Lastname</TL>: @(User.LastName)
</spna>
<div class="d-flex align-items-center mb-2">
<span class="fw-semibold text-gray-800 fs-5 m-0">
<TL>Email</TL>: <a href="/admin/users/view/@User.Id">@(User.Email)</a>
</span>
</div>
<div class="d-flex align-items-center mb-6">
<spna class="fw-semibold text-gray-800 fs-5 m-0">
<TL>Email</TL>: @(User.Email)
</spna>
</div>
<div class="d-flex align-items-center mb-6">
<spna class="fw-semibold text-gray-800 fs-5 m-0">
<div class="align-items-center mt-3">
<span class="fw-semibold text-gray-800 fs-5 m-0">
<WButton Text="@(SmartTranslateService.Translate("Close ticket"))"
WorkingText="@(SmartTranslateService.Translate("Closing"))"
CssClasses="btn-danger"
CssClasses="btn-danger float-end"
OnClick="CloseTicket">
</WButton>
</spna>
</span>
</div>
</div>
</div>

View File

@@ -15,7 +15,9 @@
<div class="card mb-5 mb-xl-10">
<div class="card-header">
<div class="card-title">
<h3 class="fw-bold m-0 text-gray-800">Persönliche Daten</h3>
<h3 class="fw-bold m-0 text-gray-800">
<TL>Personal information</TL>
</h3>
</div>
</div>
<div class="card-body border-top p-9">

View File

@@ -236,7 +236,7 @@
private async void Enable()
{
await AuditLogService.Log(AuditLogType.EnableTotp, "Totp enabled");
await AuditLogService.Log(AuditLogType.EnableTotp, x => x.Add<string>("Totp enabled"));
await TotpService.Enable();
TotpEnabled = await TotpService.GetEnabled();
TotpSecret = await TotpService.GetSecret();
@@ -262,7 +262,7 @@
private async void Disable()
{
await AuditLogService.Log(AuditLogType.DisableTotp, "Totp disabled");
await AuditLogService.Log(AuditLogType.DisableTotp, x => x.Add<string>("Totp disabled"));
await TotpService.Disable();
NavigationManager.NavigateTo(NavigationManager.Uri, true);
}
@@ -286,7 +286,7 @@
{
await UserService.ChangePassword(User, Password);
await AuditLogService.Log(AuditLogType.PasswordChange, "The password has been set to a new one");
await AuditLogService.Log(AuditLogType.PasswordChange, x => x.Add<string>("The password has been set to a new one"));
// Reload to make the user login again
NavigationManager.NavigateTo(NavigationManager.Uri, true);

View File

@@ -13,7 +13,7 @@
<div class="card">
<div class="card-body">
<LazyLoader Load="LoadMessages">
<div class="scroll-y me-n5 pe-5" style="max-height: 65vh; display: flex; flex-direction: column-reverse;">
<div class="scroll-y me-n5 pe-5" style="max-height: 55vh; display: flex; flex-direction: column-reverse;">
@foreach (var message in Messages)
{
if (message.IsSystem || message.IsSupport)
@@ -21,7 +21,7 @@
<div class="d-flex justify-content-start mb-10 ">
<div class="d-flex flex-column align-items-start">
<div class="d-flex align-items-center mb-2">
<div class="symbol symbol-35px symbol-circle ">
<div class="symbol symbol-35px symbol-circle ">
<img alt="Logo" src="@(ResourceService.Image("logo.svg"))">
</div>
<div class="ms-3">
@@ -104,10 +104,10 @@
@if (typingUsers.Any())
{
<span class="mb-5 fs-5 d-flex flex-row">
<div class="wave me-3">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="wave me-1">
<div class="dot h-5px w-5px" style="margin-right: 1px;"></div>
<div class="dot h-5px w-5px" style="margin-right: 1px;"></div>
<div class="dot h-5px w-5px"></div>
</div>
@if (typingUsers.Length > 1)
{
@@ -120,19 +120,27 @@
</span>
}
<textarea @bind="Content" @oninput="OnTyping" class="form-control mb-3" rows="1" placeholder="Type a message">
</textarea>
<div class="d-flex flex-stack">
<div class="d-flex align-items-center me-2">
<button class="btn btn-sm btn-icon btn-active-light-primary me-1" type="button">
<i class="bx bx-upload fs-3"></i>
</button>
</div>
<WButton Text="@(SmartTranslateService.Translate("Send"))"
WorkingText="@(SmartTranslateService.Translate("Sending"))"
CssClasses="btn-primary"
OnClick="Send">
</WButton>
<table class="w-100">
<tr>
<!--<td class="align-top">
<button class="btn btn-sm btn-icon btn-active-light-primary me-1" type="button">
<i class="bx bx-upload fs-3"></i>
</button>
</td>-->
<td class="w-100">
<textarea @bind="Content" @oninput="OnTyping" class="form-control mb-3 form-control-flush" rows="1" placeholder="Type a message">
</textarea>
</td>
<td class="align-top">
<WButton Text="@(SmartTranslateService.Translate("Send"))"
WorkingText="@(SmartTranslateService.Translate("Sending"))"
CssClasses="btn-primary ms-2"
OnClick="Send">
</WButton>
</td>
</tr>
</table>
</div>
</div>
</div>