From f950564000117ffa891429f041e0837b0bc942d2 Mon Sep 17 00:00:00 2001 From: Geoffroy BONNEVILLE Date: Thu, 16 Apr 2020 17:16:03 +0200 Subject: [PATCH] Update groups finally implemented Code cleanup --- ModernKeePass.Application/Application.csproj | 5 +- .../Common/Interfaces/IDatabaseProxy.cs | 6 +- .../Commands/AddHistory/AddHistoryCommand.cs | 13 ++-- .../DeleteHistory/DeleteHistoryCommand.cs | 6 +- .../RestoreHistory/RestoreHistoryCommand.cs | 13 ++-- .../Entry/Models/EntryVm.cs | 2 +- .../UpdateGroup/UpdateGroupCommand.cs | 41 ++++++++++++ .../KeePass/KeePassDatabaseClient.cs | 13 ++-- ModernKeePass/Actions/DeleteEntityAction.cs | 66 ------------------- ModernKeePass/ViewModels/EntryDetailVm.cs | 6 +- ModernKeePass/ViewModels/GroupDetailVm.cs | 16 ++++- ModernKeePass/Views/GroupDetailPage.xaml | 7 +- ModernKeePass/Views/GroupDetailPage.xaml.cs | 19 ++++++ .../SymbolPickerUserControl.xaml.cs | 10 ++- ModernKeePass/Win81App.csproj | 1 - 15 files changed, 123 insertions(+), 101 deletions(-) create mode 100644 ModernKeePass.Application/Group/Commands/UpdateGroup/UpdateGroupCommand.cs delete mode 100644 ModernKeePass/Actions/DeleteEntityAction.cs diff --git a/ModernKeePass.Application/Application.csproj b/ModernKeePass.Application/Application.csproj index 989b640..82245e8 100644 --- a/ModernKeePass.Application/Application.csproj +++ b/ModernKeePass.Application/Application.csproj @@ -94,6 +94,7 @@ + @@ -136,9 +137,7 @@ - - - + {9a0759f1-9069-4841-99e3-3bec44e17356} diff --git a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs index 7f82bb8..3e4c83c 100644 --- a/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs +++ b/ModernKeePass.Application/Common/Interfaces/IDatabaseProxy.cs @@ -34,7 +34,7 @@ namespace ModernKeePass.Application.Common.Interfaces Task MoveEntry(string parentGroupId, string entryId, int index); Task AddGroup(string parentGroupId, string groupId); void UpdateEntry(string entryId, string fieldName, object fieldValue); - void UpdateGroup(string groupId); + void UpdateGroup(GroupEntity group); Task RemoveEntry(string parentGroupId, string entryId); Task RemoveGroup(string parentGroupId, string groupId); void DeleteEntity(string entityId); @@ -43,8 +43,8 @@ namespace ModernKeePass.Application.Common.Interfaces void SortEntries(string groupId); void SortSubGroups(string groupId); - void AddHistory(string entryId); - void RestoreFromHistory(string entryId, int historyIndex); + EntryEntity AddHistory(string entryId); + EntryEntity RestoreFromHistory(string entryId, int historyIndex); void DeleteHistory(string entryId, int historyIndex); IEnumerable Search(string groupId, string text); diff --git a/ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs b/ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs index 44f67a6..19abf1c 100644 --- a/ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs +++ b/ModernKeePass.Application/Entry/Commands/AddHistory/AddHistoryCommand.cs @@ -1,27 +1,32 @@ -using MediatR; +using AutoMapper; +using MediatR; using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Entry.Models; using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Entry.Commands.AddHistory { public class AddHistoryCommand : IRequest { - public string EntryId { get; set; } + public EntryVm Entry { get; set; } public class AddHistoryCommandHandler : IRequestHandler { private readonly IDatabaseProxy _database; + private readonly IMapper _mapper; - public AddHistoryCommandHandler(IDatabaseProxy database) + public AddHistoryCommandHandler(IDatabaseProxy database, IMapper mapper) { _database = database; + _mapper = mapper; } public void Handle(AddHistoryCommand message) { if (!_database.IsOpen) throw new DatabaseClosedException(); - _database.AddHistory(message.EntryId); + var history = _database.AddHistory(message.Entry.Id); + message.Entry.History.Add(_mapper.Map(history)); } } } diff --git a/ModernKeePass.Application/Entry/Commands/DeleteHistory/DeleteHistoryCommand.cs b/ModernKeePass.Application/Entry/Commands/DeleteHistory/DeleteHistoryCommand.cs index 97918ec..f88d814 100644 --- a/ModernKeePass.Application/Entry/Commands/DeleteHistory/DeleteHistoryCommand.cs +++ b/ModernKeePass.Application/Entry/Commands/DeleteHistory/DeleteHistoryCommand.cs @@ -1,12 +1,13 @@ using MediatR; using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Entry.Models; using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Entry.Commands.DeleteHistory { public class DeleteHistoryCommand : IRequest { - public string EntryId { get; set; } + public EntryVm Entry { get; set; } public int HistoryIndex { get; set; } public class DeleteHistoryCommandHandler : IRequestHandler @@ -22,7 +23,8 @@ namespace ModernKeePass.Application.Entry.Commands.DeleteHistory { if (!_database.IsOpen) throw new DatabaseClosedException(); - _database.DeleteHistory(message.EntryId, message.HistoryIndex); + _database.DeleteHistory(message.Entry.Id, message.HistoryIndex); + message.Entry.History.RemoveAt(message.HistoryIndex); } } } diff --git a/ModernKeePass.Application/Entry/Commands/RestoreHistory/RestoreHistoryCommand.cs b/ModernKeePass.Application/Entry/Commands/RestoreHistory/RestoreHistoryCommand.cs index 1fd4373..7d67008 100644 --- a/ModernKeePass.Application/Entry/Commands/RestoreHistory/RestoreHistoryCommand.cs +++ b/ModernKeePass.Application/Entry/Commands/RestoreHistory/RestoreHistoryCommand.cs @@ -1,28 +1,33 @@ -using MediatR; +using AutoMapper; +using MediatR; using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Entry.Models; using ModernKeePass.Domain.Exceptions; namespace ModernKeePass.Application.Entry.Commands.RestoreHistory { public class RestoreHistoryCommand : IRequest { - public string EntryId { get; set; } + public EntryVm Entry { get; set; } public int HistoryIndex { get; set; } public class RestoreHistoryCommandHandler : IRequestHandler { private readonly IDatabaseProxy _database; + private readonly IMapper _mapper; - public RestoreHistoryCommandHandler(IDatabaseProxy database) + public RestoreHistoryCommandHandler(IDatabaseProxy database, IMapper mapper) { _database = database; + _mapper = mapper; } public void Handle(RestoreHistoryCommand message) { if (!_database.IsOpen) throw new DatabaseClosedException(); - _database.RestoreFromHistory(message.EntryId, message.HistoryIndex); + var entry = _database.RestoreFromHistory(message.Entry.Id, message.HistoryIndex); + message.Entry = _mapper.Map(entry); } } } diff --git a/ModernKeePass.Application/Entry/Models/EntryVm.cs b/ModernKeePass.Application/Entry/Models/EntryVm.cs index c712564..6e245ab 100644 --- a/ModernKeePass.Application/Entry/Models/EntryVm.cs +++ b/ModernKeePass.Application/Entry/Models/EntryVm.cs @@ -21,7 +21,7 @@ namespace ModernKeePass.Application.Entry.Models public string Notes { get; set; } public Uri Url { get; set; } public Dictionary AdditionalFields { get; set; } - public IEnumerable History { get; set; } + public List History { get; set; } public Icon Icon { get; set; } public Color ForegroundColor { get; set; } public Color BackgroundColor { get; set; } diff --git a/ModernKeePass.Application/Group/Commands/UpdateGroup/UpdateGroupCommand.cs b/ModernKeePass.Application/Group/Commands/UpdateGroup/UpdateGroupCommand.cs new file mode 100644 index 0000000..04125e6 --- /dev/null +++ b/ModernKeePass.Application/Group/Commands/UpdateGroup/UpdateGroupCommand.cs @@ -0,0 +1,41 @@ +using MediatR; +using ModernKeePass.Application.Common.Interfaces; +using ModernKeePass.Application.Group.Models; +using ModernKeePass.Domain.Entities; +using ModernKeePass.Domain.Enums; +using ModernKeePass.Domain.Exceptions; + +namespace ModernKeePass.Application.Group.Commands.UpdateGroup +{ + public class UpdateGroupCommand : IRequest + { + public GroupVm Group { get; set; } + public string Title { get; set; } + public Icon Icon { get; set; } + + public class UpdateGroupCommandHandler : IRequestHandler + { + private readonly IDatabaseProxy _database; + + public UpdateGroupCommandHandler(IDatabaseProxy database) + { + _database = database; + } + + public void Handle(UpdateGroupCommand message) + { + if (!_database.IsOpen) throw new DatabaseClosedException(); + + var group = new GroupEntity + { + Id = message.Group.Id, + Name = message.Title, + Icon = message.Icon + }; + _database.UpdateGroup(group); + message.Group.Title = message.Title; + message.Group.Icon = message.Icon; + } + } + } +} \ No newline at end of file diff --git a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs index b8882d9..26e8103 100644 --- a/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs +++ b/ModernKeePass.Infrastructure/KeePass/KeePassDatabaseClient.cs @@ -252,18 +252,20 @@ namespace ModernKeePass.Infrastructure.KeePass } } - public void AddHistory(string entryId) + public EntryEntity AddHistory(string entryId) { var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true); pwEntry.Touch(true); pwEntry.CreateBackup(null); + return _mapper.Map(pwEntry.History.Last()); } - public void RestoreFromHistory(string entryId, int historyIndex) + public EntryEntity RestoreFromHistory(string entryId, int historyIndex) { var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true); pwEntry.RestoreFromBackup((uint)historyIndex, _pwDatabase); pwEntry.Touch(true); + return _mapper.Map(pwEntry); } public void DeleteHistory(string entryId, int historyIndex) @@ -272,9 +274,12 @@ namespace ModernKeePass.Infrastructure.KeePass pwEntry.History.RemoveAt((uint)historyIndex); } - public void UpdateGroup(string groupId) + public void UpdateGroup(GroupEntity group) { - throw new NotImplementedException(); + var pwGroup = _pwDatabase.RootGroup.FindGroup(BuildIdFromString(group.Id), true); + pwGroup.Name = group.Name; + pwGroup.IconId = IconMapper.MapIconToPwIcon(group.Icon); + pwGroup.Touch(true); } public EntryEntity CreateEntry(string parentGroupId) diff --git a/ModernKeePass/Actions/DeleteEntityAction.cs b/ModernKeePass/Actions/DeleteEntityAction.cs deleted file mode 100644 index 70b2ef2..0000000 --- a/ModernKeePass/Actions/DeleteEntityAction.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Windows.Input; -using Windows.UI.Xaml; -using MediatR; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Xaml.Interactivity; -using ModernKeePass.Application.Database.Queries.GetDatabase; -using ModernKeePass.Common; -using ModernKeePass.Interfaces; -using ModernKeePass.ViewModels; - -namespace ModernKeePass.Actions -{ - public class DeleteEntityAction : DependencyObject, IAction - { - private readonly IMediator _mediator; - - public IVmEntity Entity - { - get { return (IVmEntity)GetValue(EntityProperty); } - set { SetValue(EntityProperty, value); } - } - - public static readonly DependencyProperty EntityProperty = - DependencyProperty.Register("Entity", typeof(IVmEntity), typeof(DeleteEntityAction), - new PropertyMetadata(null)); - - public ICommand Command - { - get { return (ICommand)GetValue(CommandProperty); } - set { SetValue(CommandProperty, value); } - } - - public static readonly DependencyProperty CommandProperty = - DependencyProperty.Register("Command", typeof(ICommand), typeof(DeleteEntityAction), - new PropertyMetadata(null)); - - public DeleteEntityAction() : this(App.Services.GetRequiredService()) { } - - public DeleteEntityAction(IMediator mediator) - { - _mediator = mediator; - } - - public object Execute(object sender, object parameter) - { - var resource = new ResourceHelper(); - var type = Entity is GroupDetailVm ? "Group" : "Entry"; - var isRecycleOnDelete = _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult().IsRecycleBinEnabled; - - var message = isRecycleOnDelete - ? resource.GetResourceValue($"{type}RecyclingConfirmation") - : resource.GetResourceValue($"{type}DeletingConfirmation"); - var text = isRecycleOnDelete ? resource.GetResourceValue($"{type}Recycled") : resource.GetResourceValue($"{type}Deleted"); - MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message, - resource.GetResourceValue("EntityDeleteActionButton"), - resource.GetResourceValue("EntityDeleteCancelButton"), a => - { - ToastNotificationHelper.ShowMovedToast(Entity, resource.GetResourceValue("EntityDeleting"), text); - Entity.MarkForDelete(resource.GetResourceValue("RecycleBinTitle")); - Command.Execute(null); - }, null).Wait(); - - return null; - } - } -} \ No newline at end of file diff --git a/ModernKeePass/ViewModels/EntryDetailVm.cs b/ModernKeePass/ViewModels/EntryDetailVm.cs index 3bcf093..1581290 100644 --- a/ModernKeePass/ViewModels/EntryDetailVm.cs +++ b/ModernKeePass/ViewModels/EntryDetailVm.cs @@ -291,12 +291,12 @@ namespace ModernKeePass.ViewModels public async Task AddHistory() { - if (_isDirty) await _mediator.Send(new AddHistoryCommand { EntryId = Id }); + if (_isDirty) await _mediator.Send(new AddHistoryCommand { Entry = History[0] }); } private async Task RestoreHistory() { - await _mediator.Send(new RestoreHistoryCommand { EntryId = Id, HistoryIndex = History.Count - SelectedIndex - 1 }); + await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 }); History.Insert(0, SelectedItem); SelectedIndex = 0; ((RelayCommand)SaveCommand).RaiseCanExecuteChanged(); @@ -304,7 +304,7 @@ namespace ModernKeePass.ViewModels public async Task DeleteHistory() { - await _mediator.Send(new DeleteHistoryCommand { EntryId = Id, HistoryIndex = History.Count - SelectedIndex - 1 }); + await _mediator.Send(new DeleteHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 }); History.RemoveAt(SelectedIndex); SelectedIndex = 0; ((RelayCommand)SaveCommand).RaiseCanExecuteChanged(); diff --git a/ModernKeePass/ViewModels/GroupDetailVm.cs b/ModernKeePass/ViewModels/GroupDetailVm.cs index 017168b..0f5b926 100644 --- a/ModernKeePass/ViewModels/GroupDetailVm.cs +++ b/ModernKeePass/ViewModels/GroupDetailVm.cs @@ -21,6 +21,7 @@ using ModernKeePass.Application.Group.Commands.MoveEntry; using ModernKeePass.Application.Group.Commands.RemoveGroup; using ModernKeePass.Application.Group.Commands.SortEntries; using ModernKeePass.Application.Group.Commands.SortGroups; +using ModernKeePass.Application.Group.Commands.UpdateGroup; using ModernKeePass.Application.Group.Models; using ModernKeePass.Application.Group.Queries.GetGroup; using ModernKeePass.Application.Group.Queries.SearchEntries; @@ -38,7 +39,7 @@ namespace ModernKeePass.ViewModels public ObservableCollection Groups { get; } public bool IsNotRoot => Database.RootGroupId != _group.Id; - + public IOrderedEnumerable> EntriesZoomedOut => from e in Entries group e by e.Title.ToUpper().FirstOrDefault() into grp orderby grp.Key @@ -49,13 +50,13 @@ namespace ModernKeePass.ViewModels public string Title { get { return _group.Title; } - set { _group.Title = value; } + set { _mediator.Send(new UpdateGroupCommand {Group = _group, Title = value, Icon = _group.Icon}).Wait(); } } public Symbol Icon { get { return (Symbol) Enum.Parse(typeof(Symbol), _group.Icon.ToString()); } - set { _group.Icon = (Icon) Enum.Parse(typeof(Icon), value.ToString()); } + set { _mediator.Send(new UpdateGroupCommand { Group = _group, Title = _group.Title, Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString()) }).Wait(); } } public bool IsEditMode @@ -69,6 +70,15 @@ namespace ModernKeePass.ViewModels } } + public bool IsRecycleOnDelete + { + get + { + var database = Database; + return database.IsRecycleBinEnabled && _parent != null && _parent.Id != database.RecycleBinId; + } + } + public IEnumerable BreadCrumb { get; } public ICommand SaveCommand { get; } diff --git a/ModernKeePass/Views/GroupDetailPage.xaml b/ModernKeePass/Views/GroupDetailPage.xaml index 3c946fe..a1e31e6 100644 --- a/ModernKeePass/Views/GroupDetailPage.xaml +++ b/ModernKeePass/Views/GroupDetailPage.xaml @@ -239,19 +239,16 @@ + SortGroupsCommand="{Binding SortGroupsCommand}" + DeleteButtonClick="TopMenu_OnDeleteButtonClick"> - - - diff --git a/ModernKeePass/Views/GroupDetailPage.xaml.cs b/ModernKeePass/Views/GroupDetailPage.xaml.cs index 4ce1bf5..95044f8 100644 --- a/ModernKeePass/Views/GroupDetailPage.xaml.cs +++ b/ModernKeePass/Views/GroupDetailPage.xaml.cs @@ -148,6 +148,25 @@ namespace ModernKeePass.Views VisualStateManager.GoToState(TopMenu, e.NewSize.Width < 800 ? "Collapsed" : "Overflowed", true); } + private async void TopMenu_OnDeleteButtonClick(object sender, RoutedEventArgs e) + { + var resource = new ResourceHelper(); + var isRecycleOnDelete = Model.IsRecycleOnDelete; + + var message = isRecycleOnDelete + ? resource.GetResourceValue("GroupRecyclingConfirmation") + : resource.GetResourceValue("GroupDeletingConfirmation"); + var text = isRecycleOnDelete ? resource.GetResourceValue("GroupRecycled") : resource.GetResourceValue("GroupDeleted"); + await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message, + resource.GetResourceValue("EntityDeleteActionButton"), + resource.GetResourceValue("EntityDeleteCancelButton"), async a => + { + //ToastNotificationHelper.ShowMovedToast(Entity, resource.GetResourceValue("EntityDeleting"), text); + await Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle")); + NavigationHelper.GoBack(); + }, null); + } + #endregion } } diff --git a/ModernKeePass/Views/UserControls/SymbolPickerUserControl.xaml.cs b/ModernKeePass/Views/UserControls/SymbolPickerUserControl.xaml.cs index e9e6844..546127b 100644 --- a/ModernKeePass/Views/UserControls/SymbolPickerUserControl.xaml.cs +++ b/ModernKeePass/Views/UserControls/SymbolPickerUserControl.xaml.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; +using ModernKeePass.Domain.Enums; // The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236 @@ -10,7 +11,7 @@ namespace ModernKeePass.Views.UserControls { public sealed partial class SymbolPickerUserControl { - public IEnumerable Symbols { get; } + public List Symbols { get; } public Symbol SelectedSymbol { @@ -27,7 +28,12 @@ namespace ModernKeePass.Views.UserControls public SymbolPickerUserControl() { InitializeComponent(); - Symbols = Enum.GetValues(typeof(Symbol)).Cast(); + Symbols = new List(); + var names = Enum.GetNames(typeof(Icon)); + foreach (var name in names) + { + Symbols.Add((Symbol) Enum.Parse(typeof(Symbol), name)); + } } private void ComboBox_OnLoaded(object sender, RoutedEventArgs e) diff --git a/ModernKeePass/Win81App.csproj b/ModernKeePass/Win81App.csproj index 0751cf2..b9c6a1c 100644 --- a/ModernKeePass/Win81App.csproj +++ b/ModernKeePass/Win81App.csproj @@ -90,7 +90,6 @@ -