mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-04 14:54:11 -04:00
Tweak DeleteFolderModal to reuse generic modal component (#1404)
This commit is contained in:
@@ -1,86 +1,73 @@
|
||||
@using AliasVault.Client.Main.Components.Layout
|
||||
@using Microsoft.Extensions.Localization
|
||||
|
||||
@* DeleteFolderModal component - modal with two delete options for a folder *@
|
||||
@if (IsOpen)
|
||||
{
|
||||
<div class="fixed inset-0 z-50 overflow-y-auto">
|
||||
<div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||
@* Background overlay *@
|
||||
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity dark:bg-gray-900 dark:bg-opacity-75" @onclick="HandleClose"></div>
|
||||
<FormModal
|
||||
IsOpen="IsOpen"
|
||||
Title="@Localizer["DeleteFolderTitle"]"
|
||||
IconBackgroundClass="bg-red-100 dark:bg-red-900/30"
|
||||
ShowDefaultFooter="false"
|
||||
OnClose="HandleClose">
|
||||
<Icon>
|
||||
<svg class="h-6 w-6 text-red-600 dark:text-red-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
|
||||
</svg>
|
||||
</Icon>
|
||||
<ChildContent>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
@string.Format(Localizer["DeleteFolderDescription"].Value, FolderName)
|
||||
</p>
|
||||
</ChildContent>
|
||||
<FooterContent>
|
||||
<div class="w-full space-y-2">
|
||||
@* Option 1: Delete folder, keep items *@
|
||||
<button
|
||||
type="button"
|
||||
@onclick="HandleDeleteFolderOnly"
|
||||
disabled="@IsDeleting"
|
||||
class="w-full flex items-center gap-3 p-3 rounded-lg border border-orange-200 bg-orange-50 hover:bg-orange-100 dark:border-orange-800 dark:bg-orange-900/20 dark:hover:bg-orange-900/30 transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<div class="flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-full bg-orange-100 dark:bg-orange-900/40">
|
||||
<svg class="w-5 h-5 text-orange-600 dark:text-orange-400" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M10 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-8l-2-2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1 text-left">
|
||||
<div class="font-medium text-orange-700 dark:text-orange-300">@Localizer["DeleteFolderOnlyTitle"]</div>
|
||||
<div class="text-sm text-orange-600/80 dark:text-orange-400/80">@Localizer["DeleteFolderOnlyDescription"]</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@* Modal panel *@
|
||||
<div class="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg dark:bg-gray-800">
|
||||
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 dark:bg-gray-800">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10 dark:bg-red-900/30">
|
||||
<svg class="h-6 w-6 text-red-600 dark:text-red-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left flex-1">
|
||||
<h3 class="text-lg font-semibold leading-6 text-gray-900 dark:text-white">
|
||||
@Localizer["DeleteFolderTitle"]
|
||||
</h3>
|
||||
<div class="mt-2">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
@string.Format(Localizer["DeleteFolderDescription"].Value, FolderName)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@* Option 2: Delete folder and contents - only show if folder has items *@
|
||||
@if (ItemCount > 0)
|
||||
{
|
||||
<button
|
||||
type="button"
|
||||
@onclick="HandleDeleteFolderAndContents"
|
||||
disabled="@IsDeleting"
|
||||
class="w-full flex items-center gap-3 p-3 rounded-lg border border-red-200 bg-red-50 hover:bg-red-100 dark:border-red-800 dark:bg-red-900/20 dark:hover:bg-red-900/30 transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<div class="flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-full bg-red-100 dark:bg-red-900/40">
|
||||
<svg class="w-5 h-5 text-red-600 dark:text-red-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 text-left">
|
||||
<div class="font-medium text-red-700 dark:text-red-300">@Localizer["DeleteFolderAndContentsTitle"]</div>
|
||||
<div class="text-sm text-red-600/80 dark:text-red-400/80">@string.Format(Localizer["DeleteFolderAndContentsDescription"].Value, ItemCount)</div>
|
||||
</div>
|
||||
</button>
|
||||
}
|
||||
|
||||
<div class="bg-gray-50 px-4 py-3 space-y-2 dark:bg-gray-800/50">
|
||||
@* Option 1: Delete folder, keep items *@
|
||||
<button
|
||||
type="button"
|
||||
@onclick="HandleDeleteFolderOnly"
|
||||
disabled="@IsDeleting"
|
||||
class="w-full flex items-center gap-3 p-3 rounded-lg border border-orange-200 bg-orange-50 hover:bg-orange-100 dark:border-orange-800 dark:bg-orange-900/20 dark:hover:bg-orange-900/30 transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<div class="flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-full bg-orange-100 dark:bg-orange-900/40">
|
||||
<svg class="w-5 h-5 text-orange-600 dark:text-orange-400" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M10 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-8l-2-2z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1 text-left">
|
||||
<div class="font-medium text-orange-700 dark:text-orange-300">@Localizer["DeleteFolderOnlyTitle"]</div>
|
||||
<div class="text-sm text-orange-600/80 dark:text-orange-400/80">@Localizer["DeleteFolderOnlyDescription"]</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@* Option 2: Delete folder and contents - only show if folder has items *@
|
||||
@if (ItemCount > 0)
|
||||
{
|
||||
<button
|
||||
type="button"
|
||||
@onclick="HandleDeleteFolderAndContents"
|
||||
disabled="@IsDeleting"
|
||||
class="w-full flex items-center gap-3 p-3 rounded-lg border border-red-200 bg-red-50 hover:bg-red-100 dark:border-red-800 dark:bg-red-900/20 dark:hover:bg-red-900/30 transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
<div class="flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-full bg-red-100 dark:bg-red-900/40">
|
||||
<svg class="w-5 h-5 text-red-600 dark:text-red-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1 text-left">
|
||||
<div class="font-medium text-red-700 dark:text-red-300">@Localizer["DeleteFolderAndContentsTitle"]</div>
|
||||
<div class="text-sm text-red-600/80 dark:text-red-400/80">@string.Format(Localizer["DeleteFolderAndContentsDescription"].Value, ItemCount)</div>
|
||||
</div>
|
||||
</button>
|
||||
}
|
||||
|
||||
@* Cancel button *@
|
||||
<button
|
||||
type="button"
|
||||
@onclick="HandleClose"
|
||||
class="w-full mt-2 inline-flex justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:hover:bg-gray-600">
|
||||
@Localizer["CancelButton"]
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@* Cancel button *@
|
||||
<button
|
||||
type="button"
|
||||
@onclick="HandleClose"
|
||||
class="w-full mt-2 inline-flex justify-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 dark:bg-gray-700 dark:text-white dark:ring-gray-600 dark:hover:bg-gray-600">
|
||||
@Localizer["CancelButton"]
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</FooterContent>
|
||||
</FormModal>
|
||||
|
||||
@code {
|
||||
[Inject]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using AliasVault.Client.Main.Models
|
||||
|
||||
@* FolderPill component - displays a folder as a compact clickable pill *@
|
||||
<button @onclick="OnClick" class="inline-flex items-center gap-2 px-3.5 py-2 text-sm rounded-lg bg-gray-100 dark:bg-gray-700/50 hover:bg-gray-200 dark:hover:bg-gray-600/50 transition-colors focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-offset-1 dark:focus:ring-offset-gray-800">
|
||||
<button @onclick="OnClick" class="inline-flex items-center gap-2 px-5 py-3 text-sm rounded-lg bg-gray-100 dark:bg-gray-700/50 hover:bg-gray-200 dark:hover:bg-gray-600/50 transition-colors focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-offset-1 dark:focus:ring-offset-gray-800">
|
||||
<svg class="w-4 h-4 text-orange-500 flex-shrink-0" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M10 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-8l-2-2z"/>
|
||||
</svg>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
Title="@GetFilterTitle()"
|
||||
Description="@Localizer["PageDescription"]">
|
||||
<TitleActions>
|
||||
<div class="relative">
|
||||
<div class="relative flex items-center gap-2">
|
||||
<button @onclick="ToggleFilterDropdown" id="filterButton" class="flex items-center gap-2 text-gray-900 dark:text-white hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none">
|
||||
<h1 class="flex items-baseline gap-1.5 text-xl font-semibold tracking-tight text-gray-900 dark:text-white sm:text-2xl">
|
||||
<span>@GetFilterTitle()</span>
|
||||
@@ -28,6 +28,15 @@
|
||||
<polyline points="6 9 12 15 18 9" />
|
||||
</svg>
|
||||
</button>
|
||||
@if (IsInFolder)
|
||||
{
|
||||
<button @onclick="ShowDeleteFolderModal" title="@Localizer["DeleteFolder"]" class="p-1.5 text-gray-400 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||
</svg>
|
||||
</button>
|
||||
}
|
||||
|
||||
@if (ShowFilterDropdown)
|
||||
{
|
||||
@@ -148,7 +157,7 @@ else
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="px-4 mb-4">
|
||||
<div class="px-4 mb-4 min-h-[250px]">
|
||||
@* Folders section - only show at root level *@
|
||||
@if (!IsInFolder && !IsSearching)
|
||||
{
|
||||
@@ -173,19 +182,6 @@ else
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Back to root button - only show when in folder *@
|
||||
@if (IsInFolder)
|
||||
{
|
||||
<div class="mb-4">
|
||||
<button @onclick="NavigateToRoot" class="inline-flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
@Localizer["BackToRoot"]
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="grid gap-4 md:grid-cols-4 xl:grid-cols-6">
|
||||
@if (Items.Count == 0 && !IsInFolder)
|
||||
{
|
||||
@@ -259,18 +255,6 @@ else
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Delete folder button - only show when in a folder *@
|
||||
@if (IsInFolder)
|
||||
{
|
||||
<button @onclick="ShowDeleteFolderModal" class="w-full mt-4 p-3 flex items-center gap-2 text-left text-red-600 dark:text-red-400 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 hover:border-red-300 dark:hover:border-red-700 transition-colors">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||
</svg>
|
||||
<span>@Localizer["DeleteFolder"]</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -491,10 +475,10 @@ else
|
||||
{
|
||||
if (Folders.Count > 0)
|
||||
{
|
||||
return "inline-flex items-center gap-1.5 px-3.5 py-2 text-sm rounded-lg transition-colors focus:outline-none text-gray-500 dark:text-gray-400 hover:text-orange-600 dark:hover:text-orange-400 hover:bg-gray-100 dark:hover:bg-gray-700/50";
|
||||
return "inline-flex items-center gap-1.5 px-5 py-3 text-sm rounded-lg transition-colors focus:outline-none text-gray-500 dark:text-gray-400 hover:text-orange-600 dark:hover:text-orange-400 hover:bg-gray-100 dark:hover:bg-gray-700/50";
|
||||
}
|
||||
|
||||
return "inline-flex items-center gap-1.5 px-3.5 py-2 text-sm rounded-lg transition-colors focus:outline-none text-gray-400 dark:text-gray-500 border border-dashed border-gray-300 dark:border-gray-600 hover:border-orange-400 dark:hover:border-orange-500 hover:text-orange-600 dark:hover:text-orange-400";
|
||||
return "inline-flex items-center gap-1.5 px-5 py-3 text-sm rounded-lg transition-colors focus:outline-none text-gray-400 dark:text-gray-500 border border-dashed border-gray-300 dark:border-gray-600 hover:border-orange-400 dark:hover:border-orange-500 hover:text-orange-600 dark:hover:text-orange-400";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user