Create entries and groups put them in Edit mode (as before)

Search now uses KeePassLib search
Code cleanup
This commit is contained in:
Geoffroy BONNEVILLE
2020-04-15 12:02:30 +02:00
parent b66e79f97c
commit 0063ef1977
14 changed files with 112 additions and 58 deletions

View File

@@ -93,6 +93,7 @@
<Compile Include="Group\Commands\DeleteEntry\DeleteEntryCommand.cs" />
<Compile Include="Group\Commands\DeleteGroup\DeleteGroupCommand.cs" />
<Compile Include="Group\Queries\GetGroup\GetGroupQuery.cs" />
<Compile Include="Group\Queries\SearchEntries\SearchEntriesQuery.cs" />
<Compile Include="Parameters\Commands\SetCipher\SetCipherCommand.cs" />
<Compile Include="Parameters\Commands\SetCompression\SetCompressionCommand.cs" />
<Compile Include="Parameters\Commands\SetHasRecycleBin\SetHasRecycleBinCommand.cs" />

View File

@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Entities;
using ModernKeePass.Domain.Enums;
@@ -28,6 +29,8 @@ namespace ModernKeePass.Application.Common.Interfaces
void UpdateCredentials(Credentials credentials);
void CloseDatabase();
EntryEntity GetEntry(string id);
GroupEntity GetGroup(string id);
Task AddEntry(string parentGroupId, string entryId);
Task MoveEntry(string parentGroupId, string entryId, int index);
Task AddGroup(string parentGroupId, string groupId);
@@ -40,7 +43,7 @@ namespace ModernKeePass.Application.Common.Interfaces
GroupEntity CreateGroup(string parentGroupId, string name, bool isRecycleBin = false);
void SortEntries(string groupId);
void SortSubGroups(string groupId);
EntryEntity GetEntry(string id);
GroupEntity GetGroup(string id);
IEnumerable<EntryEntity> Search(string groupId, string text);
}
}

View File

@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using MediatR;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Entry.Models;
using ModernKeePass.Domain.Exceptions;
namespace ModernKeePass.Application.Group.Queries.SearchEntries
{
public class SearchEntriesQuery : IRequest<IEnumerable<EntryVm>>
{
public string GroupId { get; set; }
public string SearchText { get; set; }
public class SearchEntriesQueryHandler : IRequestHandler<SearchEntriesQuery, IEnumerable<EntryVm>>
{
private readonly IDatabaseProxy _database;
private readonly IMapper _mapper;
public SearchEntriesQueryHandler(IDatabaseProxy database, IMapper mapper)
{
_database = database;
_mapper = mapper;
}
public IEnumerable<EntryVm> Handle(SearchEntriesQuery message)
{
if (!_database.IsOpen) throw new DatabaseClosedException();
return _database.Search(message.GroupId, message.SearchText).Select(e => _mapper.Map<EntryVm>(e));
}
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
@@ -9,6 +10,7 @@ using ModernKeePass.Domain.Entities;
using ModernKeePass.Domain.Enums;
using ModernKeePass.Domain.Interfaces;
using ModernKeePassLib;
using ModernKeePassLib.Collections;
using ModernKeePassLib.Cryptography.KeyDerivation;
using ModernKeePassLib.Interfaces;
using ModernKeePassLib.Keys;
@@ -311,6 +313,21 @@ namespace ModernKeePass.Infrastructure.KeePass
_pwDatabase.MasterKey = CreateCompositeKey(credentials);
}
public IEnumerable<EntryEntity> Search(string groupId, string text)
{
var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(groupId), true);
var searchResults = new PwObjectList<PwEntry>();
pwGroup.SearchEntries(new SearchParameters
{
ComparisonMode = StringComparison.OrdinalIgnoreCase,
SearchInTitles = true,
//SearchInUserNames = true,
SearchString = text
}, searchResults);
return searchResults.Select(e => _mapper.Map<EntryEntity>(e));
}
private CompositeKey CreateCompositeKey(Credentials credentials)
{
var compositeKey = new CompositeKey();

View File

@@ -58,7 +58,7 @@ namespace ModernKeePass.Actions
ToastNotificationHelper.ShowMovedToast(Entity, resource.GetResourceValue("EntityDeleting"), text);
Entity.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
Command.Execute(null);
}, null).GetAwaiter().GetResult();
}, null).Wait();
return null;
}

View File

@@ -15,7 +15,7 @@ namespace ModernKeePass.Common
messageDialog.Commands.Add(new UICommand(actionButtonText, actionCommand));
// Show the message dialog
await messageDialog.ShowAsync().AsTask();
await messageDialog.ShowAsync().AsTask().ConfigureAwait(false);
}
public static async Task ShowErrorDialog(Exception exception)
@@ -25,7 +25,7 @@ namespace ModernKeePass.Common
var messageDialog = CreateBasicDialog(exception.Message, exception.StackTrace, "OK");
// Show the message dialog
await messageDialog.ShowAsync().AsTask();;
await messageDialog.ShowAsync().AsTask().ConfigureAwait(false);
}
public static async Task ShowNotificationDialog(string title, string message)
@@ -33,7 +33,7 @@ namespace ModernKeePass.Common
var dialog = CreateBasicDialog(title, message, "OK");
// Show the message dialog
await dialog.ShowAsync().AsTask();;
await dialog.ShowAsync().AsTask().ConfigureAwait(false);
}
private static MessageDialog CreateBasicDialog(string title, string message, string dismissActionText, UICommandInvokedHandler cancelCommand = null)

View File

@@ -0,0 +1,8 @@
namespace ModernKeePass.Models
{
public class NavigationItem
{
public string Id { get; set; }
public bool IsNew { get; set; }
}
}

View File

@@ -181,12 +181,6 @@ namespace ModernKeePass.ViewModels
set { SetProperty(ref _isEditMode, value); }
}
public bool IsVisible
{
get { return _isVisible; }
set { SetProperty(ref _isVisible, value); }
}
public bool IsRevealPassword
{
get { return _isRevealPassword; }
@@ -205,21 +199,18 @@ namespace ModernKeePass.ViewModels
private bool _isEditMode;
private bool _isRevealPassword;
private double _passwordLength = 25;
private bool _isVisible = true;
private bool _isSelected;
public EntryDetailVm() { }
internal EntryDetailVm(string entryId, bool isNewEntry = false) : this(entryId, App.Services.GetRequiredService<IMediator>(), isNewEntry) { }
internal EntryDetailVm(string entryId) : this(entryId, App.Services.GetRequiredService<IMediator>()) { }
public EntryDetailVm(string entryId, IMediator mediator, bool isNewEntry = false)
public EntryDetailVm(string entryId, IMediator mediator)
{
_mediator = mediator;
_entry = _mediator.Send(new GetEntryQuery {Id = entryId}).GetAwaiter().GetResult();
_parent = _mediator.Send(new GetGroupQuery {Id = _entry.ParentGroupId}).GetAwaiter().GetResult();
History = _entry.History;
_isEditMode = isNewEntry;
if (isNewEntry) GeneratePassword().GetAwaiter().GetResult();
IsSelected = true;
SaveCommand = new RelayCommand(async () => await SaveChanges(), () => Database.IsDirty);

View File

@@ -23,6 +23,7 @@ using ModernKeePass.Application.Group.Commands.SortEntries;
using ModernKeePass.Application.Group.Commands.SortGroups;
using ModernKeePass.Application.Group.Models;
using ModernKeePass.Application.Group.Queries.GetGroup;
using ModernKeePass.Application.Group.Queries.SearchEntries;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Enums;
@@ -35,22 +36,7 @@ namespace ModernKeePass.ViewModels
public ObservableCollection<EntryVm> Entries { get; }
public ObservableCollection<GroupVm> Groups { get; }
public IEnumerable<EntryVm> SubEntries
{
get
{
var subEntries = new List<EntryVm>();
subEntries.AddRange(Entries);
foreach (var group in Groups)
{
subEntries.AddRange(group.Entries);
}
return subEntries;
}
}
public bool IsNotRoot => Database.RootGroupId != _group.Id;
public IOrderedEnumerable<IGrouping<char, EntryVm>> EntriesZoomedOut => from e in Entries
@@ -83,12 +69,6 @@ namespace ModernKeePass.ViewModels
}
}
public bool IsMenuClosed
{
get { return _isMenuClosed; }
set { SetProperty(ref _isMenuClosed, value); }
}
public IEnumerable<GroupVm> BreadCrumb { get; }
public ICommand SaveCommand { get; }
@@ -103,14 +83,13 @@ namespace ModernKeePass.ViewModels
private readonly GroupVm _parent;
private bool _isEditMode;
private EntryVm _reorderedEntry;
private bool _isMenuClosed = true;
public GroupDetailVm() {}
internal GroupDetailVm(string groupId) : this(groupId, App.Services.GetRequiredService<IMediator>())
{ }
public GroupDetailVm(string groupId, IMediator mediator, bool isEditMode = false)
public GroupDetailVm(string groupId, IMediator mediator)
{
_mediator = mediator;
_group = _mediator.Send(new GetGroupQuery { Id = groupId }).GetAwaiter().GetResult();
@@ -119,7 +98,6 @@ namespace ModernKeePass.ViewModels
_parent = _mediator.Send(new GetGroupQuery { Id = _group.ParentGroupId }).GetAwaiter().GetResult();
BreadCrumb = new List<GroupVm> {_parent};
}
_isEditMode = isEditMode;
SaveCommand = new RelayCommand(async () => await SaveChanges(), () => Database.IsDirty);
SortEntriesCommand = new RelayCommand(async () => await SortEntriesAsync(), () => IsEditMode);
@@ -152,6 +130,11 @@ namespace ModernKeePass.ViewModels
await _mediator.Send(new RemoveGroupCommand {ParentGroup = _parent, Group = _group });
}
public async Task<IEnumerable<EntryVm>> Search(string queryText)
{
return await _mediator.Send(new SearchEntriesQuery {GroupId = Id, SearchText = queryText});
}
private async Task SaveChanges()
{
await _mediator.Send(new SaveDatabaseCommand());

View File

@@ -10,6 +10,7 @@ using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Models;
using ModernKeePass.Views;
namespace ModernKeePass.ViewModels
@@ -128,7 +129,7 @@ namespace ModernKeePass.ViewModels
Title = database.Name,
PageType = typeof(GroupDetailPage),
Destination = referenceFrame,
Parameter = database.RootGroupId,
Parameter = new NavigationItem { Id = database.RootGroupId },
Group = "Databases",
SymbolIcon = Symbol.ProtectedDocument
});

View File

@@ -2,6 +2,7 @@
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Common;
using ModernKeePass.Models;
using ModernKeePass.ViewModels;
// Pour en savoir plus sur le modèle d'élément Page Détail de l'élément, consultez la page http://go.microsoft.com/fwlink/?LinkId=234232
@@ -39,11 +40,15 @@ namespace ModernKeePass.Views
/// Le paramètre de navigation est disponible dans la méthode LoadState
/// en plus de l'état de page conservé durant une session antérieure.
protected override void OnNavigatedTo(NavigationEventArgs e)
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
NavigationHelper.OnNavigatedTo(e);
var args = e.Parameter as string;
if (args != null) DataContext = new EntryDetailVm(args);
var args = e.Parameter as NavigationItem;
if (args != null)
{
DataContext = new EntryDetailVm(args.Id) { IsEditMode = args.IsNew };
await Model.GeneratePassword();
}
}
protected override async void OnNavigatedFrom(NavigationEventArgs e)

View File

@@ -48,7 +48,7 @@
<ColumnDefinition Width="{StaticResource ExpandedMenuGridLength}" x:Name="LeftListViewColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<userControls:HamburgerMenuUserControl x:Uid="GroupsLeftListView" ItemsSource="{Binding Groups}" SelectionChanged="groups_SelectionChanged" ButtonClicked="CreateGroup_ButtonClick" ResizeTarget="{Binding ElementName=LeftListViewColumn}" IsOpen="True" />
<userControls:HamburgerMenuUserControl x:Uid="GroupsLeftListView" ItemsSource="{Binding Groups}" SelectionChanged="groups_SelectionChanged" ButtonClicked="CreateGroup_ButtonClick" ResizeTarget="{Binding ElementName=LeftListViewColumn}" IsOpen="True" IsButtonVisible="Visible" />
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />

View File

@@ -7,6 +7,7 @@ using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Common;
using ModernKeePass.Events;
using ModernKeePass.Models;
using ModernKeePass.ViewModels;
using EntryVm = ModernKeePass.Application.Entry.Models.EntryVm;
@@ -53,9 +54,9 @@ namespace ModernKeePass.Views
DataContext = new GroupDetailVm(args.RootGroupId);
else
{
var id = e.Parameter as string;
if (id != null)
DataContext = new GroupDetailVm(id);
var navigationItem = e.Parameter as NavigationItem;
if (navigationItem != null)
DataContext = new GroupDetailVm(navigationItem.Id) { IsEditMode = navigationItem.IsNew };
}
}
@@ -77,7 +78,7 @@ namespace ModernKeePass.Views
return;
default:
var group = listView?.SelectedItem as Application.Group.Models.GroupVm;
Frame.Navigate(typeof(GroupDetailPage), group?.Id);
Frame.Navigate(typeof(GroupDetailPage), new NavigationItem { Id = group?.Id });
break;
}
}
@@ -90,7 +91,7 @@ namespace ModernKeePass.Views
return;
default:
var entry = GridView.SelectedItem as EntryVm;
Frame.Navigate(typeof(EntryDetailPage), entry?.Id);
Frame.Navigate(typeof(EntryDetailPage), new NavigationItem { Id = entry?.Id });
break;
}
}
@@ -105,11 +106,19 @@ namespace ModernKeePass.Views
}
private async void CreateEntry_ButtonClick(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(EntryDetailPage), await Model.AddNewEntry());
Frame.Navigate(typeof(EntryDetailPage), new NavigationItem
{
Id = await Model.AddNewEntry(),
IsNew = true
});
}
private async void CreateGroup_ButtonClick(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(GroupDetailPage), await Model.AddNewGroup());
Frame.Navigate(typeof(GroupDetailPage), new NavigationItem
{
Id = await Model.AddNewGroup(),
IsNew = true
});
}
private void GridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
@@ -118,10 +127,10 @@ namespace ModernKeePass.Views
e.Data.RequestedOperation = DataPackageOperation.Move;
}
private void SearchBox_OnSuggestionsRequested(SearchBox sender, SearchBoxSuggestionsRequestedEventArgs args)
private async void SearchBox_OnSuggestionsRequested(SearchBox sender, SearchBoxSuggestionsRequestedEventArgs args)
{
var imageUri = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appdata://Assets/ModernKeePass-SmallLogo.scale-80.png"));
var results = Model.SubEntries.Where(e => e.Title.IndexOf(args.QueryText, StringComparison.OrdinalIgnoreCase) >= 0).Take(5);
var results = (await Model.Search(args.QueryText)).Take(5);
foreach (var result in results)
{
args.Request.SearchSuggestionCollection.AppendResultSuggestion(result.Title, result.ParentGroupName, result.Id, imageUri, string.Empty);
@@ -130,7 +139,7 @@ namespace ModernKeePass.Views
private void SearchBox_OnResultSuggestionChosen(SearchBox sender, SearchBoxResultSuggestionChosenEventArgs args)
{
Frame.Navigate(typeof(EntryDetailPage), args.Tag);
Frame.Navigate(typeof(EntryDetailPage), new NavigationItem { Id = args.Tag });
}
private void GroupDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)

View File

@@ -102,6 +102,7 @@
<Compile Include="Converters\IconToSymbolConverter.cs" />
<Compile Include="DependencyInjection.cs" />
<Compile Include="Extensions\ColorExtensions.cs" />
<Compile Include="Models\NavigationItem.cs" />
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
@@ -556,6 +557,7 @@
<Name>Infrastructure</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0' ">
<VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup>