mirror of
https://github.com/KeyKeeperApp/KeyKeeper.git
synced 2026-05-19 06:46:32 +03:00
add "Add to group" context menu action
This commit is contained in:
@@ -126,6 +126,23 @@ public class UnlockedRepositoryViewModel : ViewModelBase
|
|||||||
OnPropertyChanged(nameof(Passwords));
|
OnPropertyChanged(nameof(Passwords));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AddEntryToGroup(PassStoreEntry entry, PassStoreEntryGroup targetGroup)
|
||||||
|
{
|
||||||
|
PassStoreEntryPassword? pwd = FollowLinkIfNeeded(entry);
|
||||||
|
if (pwd == null) return false;
|
||||||
|
|
||||||
|
foreach (var bl in pwd.Backlinks)
|
||||||
|
{
|
||||||
|
if (bl is PassStoreEntryLink lnk && lnk.Parent == targetGroup)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
passStore.AddEntry(targetGroup, new PassStoreEntryLink(Guid.NewGuid(), DateTime.Now, DateTime.Now, pwd.Id, pwd));
|
||||||
|
|
||||||
|
HasUnsavedChanges = true;
|
||||||
|
OnPropertyChanged(nameof(Passwords));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateEntry(PassStoreEntryPassword updatedEntry)
|
public void UpdateEntry(PassStoreEntryPassword updatedEntry)
|
||||||
{
|
{
|
||||||
passStore.UpdateEntry(null, updatedEntry.Id, updatedEntry);
|
passStore.UpdateEntry(null, updatedEntry.Id, updatedEntry);
|
||||||
|
|||||||
@@ -154,10 +154,11 @@
|
|||||||
</TextBlock>
|
</TextBlock>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Border.ContextMenu>
|
<Border.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu Opened="EntryContextMenu_Opening">
|
||||||
<MenuItem Name="entryCtxMenuCopyUsername" Header="Copy username" Click="EntryContextMenuItem_Click"/>
|
<MenuItem Name="entryCtxMenuCopyUsername" Header="Copy username" Click="EntryContextMenuItem_Click"/>
|
||||||
<MenuItem Name="entryCtxMenuCopyPassword" Header="Copy password" Click="EntryContextMenuItem_Click"/>
|
<MenuItem Name="entryCtxMenuCopyPassword" Header="Copy password" Click="EntryContextMenuItem_Click"/>
|
||||||
<MenuItem Name="entryCtxMenuEdit" Header="Edit" Click="EntryContextMenuItem_Click"/>
|
<MenuItem Name="entryCtxMenuEdit" Header="Edit" Click="EntryContextMenuItem_Click"/>
|
||||||
|
<MenuItem Name="entryCtxMenuAddToGroup" Header="Add to group" />
|
||||||
<MenuItem Name="entryCtxMenuDelete" Header="Delete" Click="EntryContextMenuItem_Click"/>
|
<MenuItem Name="entryCtxMenuDelete" Header="Delete" Click="EntryContextMenuItem_Click"/>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</Border.ContextMenu>
|
</Border.ContextMenu>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
@@ -14,6 +15,7 @@ public partial class RepositoryWindow : Window
|
|||||||
{
|
{
|
||||||
private bool allowClose;
|
private bool allowClose;
|
||||||
private bool closeConfirmationShown;
|
private bool closeConfirmationShown;
|
||||||
|
private PassStoreEntry? _contextMenuEntry;
|
||||||
|
|
||||||
public RepositoryWindow(RepositoryWindowViewModel model)
|
public RepositoryWindow(RepositoryWindowViewModel model)
|
||||||
{
|
{
|
||||||
@@ -223,6 +225,66 @@ public partial class RepositoryWindow : Window
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void EntryContextMenu_Opening(object? sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
if (sender is not ContextMenu contextMenu || DataContext is not RepositoryWindowViewModel vm ||
|
||||||
|
vm.CurrentPage is not UnlockedRepositoryViewModel pageVm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_contextMenuEntry = null;
|
||||||
|
|
||||||
|
if (contextMenu.Parent?.Parent is Border border && border.DataContext is PassStoreEntry entry)
|
||||||
|
{
|
||||||
|
_contextMenuEntry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
var addToGroupItem = contextMenu.Items
|
||||||
|
.OfType<MenuItem>()
|
||||||
|
.FirstOrDefault(m => m.Name == "entryCtxMenuAddToGroup");
|
||||||
|
|
||||||
|
if (addToGroupItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addToGroupItem.Items.Clear();
|
||||||
|
|
||||||
|
var nonDefaultGroups = pageVm.PasswordGroups
|
||||||
|
.Where(g => g.GroupType != FileFormatConstants.GROUP_TYPE_DEFAULT)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
EventHandler<RoutedEventArgs> onSubmenuClick = (sender, args) => AddToGroup_Click(sender, args, _contextMenuEntry!);
|
||||||
|
foreach (var group in nonDefaultGroups)
|
||||||
|
{
|
||||||
|
var menuItem = new MenuItem
|
||||||
|
{
|
||||||
|
Header = group.DisplayName,
|
||||||
|
Tag = group
|
||||||
|
};
|
||||||
|
menuItem.Click += onSubmenuClick;
|
||||||
|
addToGroupItem.Items.Add(menuItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddToGroup_Click(object? sender, RoutedEventArgs args, PassStoreEntry entry)
|
||||||
|
{
|
||||||
|
if (sender is not MenuItem item || item.Tag is not PassStoreEntryGroup targetGroup)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (entry == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (DataContext is not RepositoryWindowViewModel vm ||
|
||||||
|
vm.CurrentPage is not UnlockedRepositoryViewModel pageVm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var notificationHost = this.FindControlRecursive<ToastNotificationHost>("NotificationHost");
|
||||||
|
|
||||||
|
if (pageVm.AddEntryToGroup(entry, targetGroup))
|
||||||
|
notificationHost?.Show($"Added to {targetGroup.DisplayName}");
|
||||||
|
else
|
||||||
|
notificationHost?.Show($"This entry is already in {targetGroup.DisplayName}!");
|
||||||
|
_contextMenuEntry = null;
|
||||||
|
}
|
||||||
|
|
||||||
private async void EntryContextMenuItem_Click(object sender, RoutedEventArgs args)
|
private async void EntryContextMenuItem_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Source is StyledElement s && s.DataContext is PassStoreEntry ent)
|
if (args.Source is StyledElement s && s.DataContext is PassStoreEntry ent)
|
||||||
|
|||||||
Reference in New Issue
Block a user