mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-03-23 09:03:15 -04:00
Add GlobalNotificationService (#21)
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
<div class="p-4 mb-4 text-sm text-green-800 rounded-lg bg-green-50 dark:bg-gray-800 dark:text-green-400" role="alert">
|
||||
<div class="p-4 mb-4 text-sm text-green-800 rounded-lg bg-green-50 dark:bg-gray-800 dark:text-green-400 border-2" role="alert">
|
||||
@Message
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
@inject GlobalNotificationService GlobalNotificationService
|
||||
@implements IDisposable
|
||||
|
||||
@foreach (var message in Messages)
|
||||
{
|
||||
if (message.Key == "success")
|
||||
{
|
||||
<AlertMessageSuccess Message="@message.Value" />
|
||||
}
|
||||
}
|
||||
@foreach (var message in Messages)
|
||||
{
|
||||
if (message.Key == "error")
|
||||
{
|
||||
<AlertMessageError Message="@message.Value" />
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
private Dictionary<string, string> Messages { get; set; } = new();
|
||||
private bool _onChangeSubscribed = false;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
// We subscribe to the OnChange event of the PortalMessageService to update the UI when a new message is added
|
||||
RefreshAddMessages();
|
||||
GlobalNotificationService.OnChange += RefreshAddMessages;
|
||||
_onChangeSubscribed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
// We unsubscribe from the OnChange event of the PortalMessageService when the component is disposed
|
||||
if (_onChangeSubscribed)
|
||||
{
|
||||
GlobalNotificationService.OnChange -= RefreshAddMessages;
|
||||
_onChangeSubscribed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the messages by adding any new messages from the PortalMessageService.
|
||||
/// </summary>
|
||||
public void RefreshAddMessages()
|
||||
{
|
||||
// We retrieve any additional messages from the GlobalNotificationService that we do not yet have.
|
||||
var newMessages = GlobalNotificationService.GetMessagesForDisplay();
|
||||
foreach (var message in newMessages)
|
||||
{
|
||||
if (!Messages.ContainsValue(message.Value))
|
||||
{
|
||||
Messages.Add(message.Key, message.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove messages that are no longer in the GlobalNotificationService and have already been displayed.
|
||||
var keysToRemove = Messages.Keys.Except(newMessages.Keys).ToList();
|
||||
foreach (var key in keysToRemove)
|
||||
{
|
||||
Messages.Remove(key);
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
@page "/add-alias"
|
||||
@page "/alias/{id:guid}/edit"
|
||||
|
||||
@inherits PageBase
|
||||
@inject NavigationManager Navigation
|
||||
@inject AliasService AliasService
|
||||
@inherits PageBase
|
||||
@using AliasGenerators.Implementations
|
||||
@using AliasGenerators.Password.Implementations
|
||||
@using AliasVault.Shared.Models.WebApi
|
||||
@using AliasVault.WebApp.Services
|
||||
|
||||
@if (EditMode)
|
||||
{
|
||||
@@ -296,11 +294,13 @@ else
|
||||
if (Id is not null)
|
||||
{
|
||||
await AliasService.UpdateAliasAsync(Obj, Id.Value);
|
||||
GlobalNotificationService.AddSuccessMessage("Alias updated successfully.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Id = await AliasService.InsertAliasAsync(Obj);
|
||||
GlobalNotificationService.AddSuccessMessage("Alias created successfully.");
|
||||
}
|
||||
|
||||
IsSaving = false;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
@page "/alias/{id:guid}/delete"
|
||||
|
||||
@using AliasVault.Shared.Models.WebApi
|
||||
@using AliasVault.WebApp.Services
|
||||
@inherits PageBase
|
||||
@using AliasVault.Shared.Models.WebApi
|
||||
@inject AliasService AliasService
|
||||
|
||||
<LayoutPageTitle>Delete alias</LayoutPageTitle>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
@page "/alias/{id:guid}"
|
||||
@inherits PageBase
|
||||
@using AliasVault.Shared.Models.WebApi
|
||||
@using AliasVault.WebApp.Services
|
||||
@using AliasVault.WebApp.Components.Email
|
||||
@inject AliasService AliasService
|
||||
@inherits PageBase
|
||||
|
||||
<LayoutPageTitle>View alias</LayoutPageTitle>
|
||||
|
||||
@@ -13,9 +12,12 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<div class="grid grid-cols-2 px-4 pt-6 md:grid-cols-3 lg:gap-4 dark:bg-gray-900">
|
||||
<div class="mb-4 col-span-full xl:mb-2">
|
||||
<Breadcrumb BreadcrumbItems="BreadcrumbItems"/>
|
||||
<GlobalNotificationDisplay />
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">View alias</h1>
|
||||
<div class="flex">
|
||||
@@ -28,6 +30,7 @@ else
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Content -->
|
||||
<div class="col-span-full lg:col-auto">
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
namespace AliasVault.WebApp.Pages.Base;
|
||||
|
||||
using AliasVault.WebApp.Components.Models;
|
||||
using AliasVault.WebApp.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.JSInterop;
|
||||
@@ -33,6 +34,12 @@ public class PageBase : OwningComponentBase
|
||||
[Inject]
|
||||
public AuthenticationStateProvider AuthStateProvider { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the GlobalNotificationService.
|
||||
/// </summary>
|
||||
[Inject]
|
||||
public GlobalNotificationService GlobalNotificationService { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IJSRuntime.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
@page "/"
|
||||
@page "/aliases"
|
||||
@using AliasVault.WebApp.Components.Alias
|
||||
@using AliasVault.WebApp.Services
|
||||
@inject AliasService AliasService
|
||||
@inherits PageBase
|
||||
@using AliasVault.WebApp.Components.Alias
|
||||
@inject AliasService AliasService
|
||||
|
||||
<LayoutPageTitle>Home</LayoutPageTitle>
|
||||
|
||||
@@ -22,13 +21,13 @@
|
||||
|
||||
@if (IsLoading)
|
||||
{
|
||||
<LoadingIndicator />
|
||||
<LoadingIndicator />
|
||||
}
|
||||
|
||||
<div class="grid gap-4 px-4 mb-4 md:grid-cols-4 xl:grid-cols-6">
|
||||
@foreach (var alias in Aliases)
|
||||
{
|
||||
<Alias Obj="@alias"/>
|
||||
<Alias Obj="@alias"/>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ builder.Services.AddTransient<AliasVaultApiHandlerService>();
|
||||
builder.Services.AddScoped<AuthService>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider, AuthStateProvider>();
|
||||
builder.Services.AddScoped<AliasService>();
|
||||
builder.Services.AddScoped<GlobalNotificationService>();
|
||||
builder.Services.AddSingleton<ClipboardCopyService>();
|
||||
builder.Services.AddAuthorizationCore();
|
||||
builder.Services.AddBlazoredLocalStorage();
|
||||
|
||||
63
src/AliasVault.WebApp/Services/GlobalNotificationService.cs
Normal file
63
src/AliasVault.WebApp/Services/GlobalNotificationService.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="GlobalNotificationService.cs" company="lanedirt">
|
||||
// Copyright (c) lanedirt. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace AliasVault.WebApp.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Handles global notifications that should be displayed to the user, such as success or error messages. These messages
|
||||
/// are stored in this object which is scoped to the current session. This allows the messages to be cached until
|
||||
/// they actually have been displayed. So they can survive redirects and page reloads.
|
||||
/// </summary>
|
||||
public class GlobalNotificationService
|
||||
{
|
||||
/// <summary>
|
||||
/// Allow other components to subscribe to changes in the event object.
|
||||
/// </summary>
|
||||
public event Action? OnChange;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets success messages that should be displayed to the user. A default set of success messages is added in the parent OnInitialized method.
|
||||
/// </summary>
|
||||
protected List<string> SuccessMessages { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a success message to the list of messages that should be displayed to the user.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to add.</param>
|
||||
/// <param name="notifyStateChanged">Whether to notify state change to subscribers. Defaults to true.</param>
|
||||
public void AddSuccessMessage(string message, bool notifyStateChanged = true)
|
||||
{
|
||||
SuccessMessages.Add(message);
|
||||
|
||||
// Notify subscribers that a message has been added.
|
||||
if (notifyStateChanged)
|
||||
{
|
||||
NotifyStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a dictionary with messages that should be displayed to the user. After this method is called,
|
||||
/// the messages are automatically cleared.
|
||||
/// </summary>
|
||||
/// <returns>Dictionary with messages that are ready to be displayed on the next page load.</returns>
|
||||
public Dictionary<string, string> GetMessagesForDisplay()
|
||||
{
|
||||
var messages = new Dictionary<string, string>();
|
||||
foreach (var message in SuccessMessages)
|
||||
{
|
||||
messages.Add("success", message);
|
||||
}
|
||||
|
||||
// Clear messages
|
||||
SuccessMessages.Clear();
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
private void NotifyStateChanged() => OnChange?.Invoke();
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
@using AliasVault.WebApp.Components.Alerts
|
||||
@using AliasVault.WebApp.Components.Loading
|
||||
@using AliasVault.WebApp.Pages.Base
|
||||
@using AliasVault.WebApp.Services
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
||||
@using Blazored.LocalStorage
|
||||
|
||||
@@ -714,10 +714,6 @@ video {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.me-2 {
|
||||
margin-inline-end: 0.5rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
@@ -770,10 +766,6 @@ video {
|
||||
height: 1.5rem;
|
||||
}
|
||||
|
||||
.h-7 {
|
||||
height: 1.75rem;
|
||||
}
|
||||
|
||||
.h-8 {
|
||||
height: 2rem;
|
||||
}
|
||||
@@ -786,10 +778,6 @@ video {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.h-3 {
|
||||
height: 0.75rem;
|
||||
}
|
||||
|
||||
.w-1\/2 {
|
||||
width: 50%;
|
||||
}
|
||||
@@ -822,10 +810,6 @@ video {
|
||||
width: 16rem;
|
||||
}
|
||||
|
||||
.w-7 {
|
||||
width: 1.75rem;
|
||||
}
|
||||
|
||||
.w-8 {
|
||||
width: 2rem;
|
||||
}
|
||||
@@ -834,10 +818,6 @@ video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-3 {
|
||||
width: 0.75rem;
|
||||
}
|
||||
|
||||
.min-w-full {
|
||||
min-width: 100%;
|
||||
}
|
||||
@@ -938,12 +918,6 @@ video {
|
||||
margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.space-x-6 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(1.5rem * var(--tw-space-x-reverse));
|
||||
@@ -1016,10 +990,6 @@ video {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.rounded-md {
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
.rounded-l-lg {
|
||||
border-top-left-radius: 0.5rem;
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
@@ -1046,6 +1016,11 @@ video {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.border-blue-700 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(29 78 216 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-gray-200 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(229 231 235 / var(--tw-border-opacity));
|
||||
@@ -1056,31 +1031,11 @@ video {
|
||||
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-green-100 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(220 252 231 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-green-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(34 197 94 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-orange-100 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(255 237 213 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-purple-100 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(243 232 255 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-blue-700 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(29 78 216 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.bg-blue-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
|
||||
@@ -1111,11 +1066,6 @@ video {
|
||||
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(220 252 231 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-50 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(240 253 244 / var(--tw-bg-opacity));
|
||||
@@ -1126,11 +1076,6 @@ video {
|
||||
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-orange-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 237 213 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-primary-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(214 131 56 / var(--tw-bg-opacity));
|
||||
@@ -1141,11 +1086,6 @@ video {
|
||||
background-color: rgb(184 112 47 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-purple-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(243 232 255 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-red-50 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 242 242 / var(--tw-bg-opacity));
|
||||
@@ -1161,11 +1101,6 @@ video {
|
||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-blue-700 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(29 78 216 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-opacity-50 {
|
||||
--tw-bg-opacity: 0.5;
|
||||
}
|
||||
@@ -1190,16 +1125,6 @@ video {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.px-2\.5 {
|
||||
padding-left: 0.625rem;
|
||||
padding-right: 0.625rem;
|
||||
}
|
||||
|
||||
.px-3 {
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
@@ -1220,16 +1145,6 @@ video {
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.py-0 {
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.py-0\.5 {
|
||||
padding-top: 0.125rem;
|
||||
padding-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.py-1 {
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
@@ -1352,6 +1267,11 @@ video {
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.text-blue-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(29 78 216 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-200 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(229 231 235 / var(--tw-text-opacity));
|
||||
@@ -1387,21 +1307,11 @@ video {
|
||||
color: rgb(22 101 52 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-orange-800 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(154 52 18 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-primary-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(184 112 47 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-purple-800 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(107 33 168 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-red-800 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(153 27 27 / var(--tw-text-opacity));
|
||||
@@ -1412,11 +1322,6 @@ video {
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-blue-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(29 78 216 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.opacity-0 {
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -1478,6 +1383,11 @@ video {
|
||||
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-gray-50:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-gray-800:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
|
||||
@@ -1508,16 +1418,6 @@ video {
|
||||
background-color: rgb(153 27 27 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-blue-800:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(30 64 175 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-gray-50:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:text-gray-900:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(17 24 39 / var(--tw-text-opacity));
|
||||
@@ -1598,6 +1498,11 @@ video {
|
||||
border-color: rgb(75 85 99 / var(--tw-divide-opacity));
|
||||
}
|
||||
|
||||
.dark\:border-blue-500:is(.dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(59 130 246 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:border-gray-600:is(.dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(75 85 99 / var(--tw-border-opacity));
|
||||
@@ -1608,26 +1513,6 @@ video {
|
||||
border-color: rgb(55 65 81 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:border-green-500:is(.dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(34 197 94 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:border-orange-300:is(.dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(253 186 116 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:border-purple-500:is(.dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(168 85 247 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:border-blue-500:is(.dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(59 130 246 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.dark\:bg-blue-500:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
|
||||
@@ -1673,15 +1558,15 @@ video {
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:bg-blue-600:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:bg-opacity-80:is(.dark *) {
|
||||
--tw-bg-opacity: 0.8;
|
||||
}
|
||||
|
||||
.dark\:text-blue-500:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(59 130 246 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-gray-300:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(209 213 219 / var(--tw-text-opacity));
|
||||
@@ -1702,11 +1587,6 @@ video {
|
||||
color: rgb(74 222 128 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-orange-300:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(253 186 116 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-primary-200:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(251 203 116 / var(--tw-text-opacity));
|
||||
@@ -1717,11 +1597,6 @@ video {
|
||||
color: rgb(244 149 65 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-purple-400:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(192 132 252 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-red-400:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(248 113 113 / var(--tw-text-opacity));
|
||||
@@ -1732,11 +1607,6 @@ video {
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:text-blue-500:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(59 130 246 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:placeholder-gray-400:is(.dark *)::-moz-placeholder {
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(156 163 175 / var(--tw-placeholder-opacity));
|
||||
@@ -1751,6 +1621,11 @@ video {
|
||||
--tw-ring-offset-color: #1f2937;
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-blue-500:hover:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-blue-600:hover:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
|
||||
@@ -1786,16 +1661,6 @@ video {
|
||||
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-blue-700:hover:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(29 78 216 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-blue-500:hover:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.dark\:hover\:text-primary-500:hover:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(244 149 65 / var(--tw-text-opacity));
|
||||
|
||||
@@ -86,8 +86,8 @@ public class AliasTests : PlaywrightTest
|
||||
await submitButton.ClickAsync();
|
||||
await WaitForURLAsync("**/alias/**", "View alias");
|
||||
|
||||
// Check if the alias was correctly updated.
|
||||
pageContent = await Page.TextContentAsync("body");
|
||||
Assert.That(pageContent, Does.Contain("Alias updated"), "Alias update confirmation message not shown.");
|
||||
Assert.That(pageContent, Does.Contain(serviceNameAfter), "Alias not updated correctly.");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user