Update groups finally implemented

Code cleanup
This commit is contained in:
Geoffroy BONNEVILLE
2020-04-16 17:16:03 +02:00
parent 9befdc321a
commit f950564000
15 changed files with 123 additions and 101 deletions

View File

@@ -94,6 +94,7 @@
<Compile Include="Entry\Queries\GetEntry\GetEntryQuery.cs" />
<Compile Include="Group\Commands\DeleteEntry\DeleteEntryCommand.cs" />
<Compile Include="Group\Commands\DeleteGroup\DeleteGroupCommand.cs" />
<Compile Include="Group\Commands\UpdateGroup\UpdateGroupCommand.cs" />
<Compile Include="Group\Queries\GetGroup\GetGroupQuery.cs" />
<Compile Include="Group\Queries\SearchEntries\SearchEntriesQuery.cs" />
<Compile Include="Parameters\Commands\SetCipher\SetCipherCommand.cs" />
@@ -136,9 +137,7 @@
<Compile Include="Security\Queries\EstimatePasswordComplexity\EstimatePasswordComplexityQuery.cs" />
<Content Include="Services\DatabaseService.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Group\Commands\UpdateGroup\" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\ModernKeePass.Domain\Domain.csproj">
<Project>{9a0759f1-9069-4841-99e3-3bec44e17356}</Project>

View File

@@ -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<EntryEntity> Search(string groupId, string text);

View File

@@ -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<AddHistoryCommand>
{
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<EntryVm>(history));
}
}
}

View File

@@ -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<DeleteHistoryCommand>
@@ -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);
}
}
}

View File

@@ -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<RestoreHistoryCommand>
{
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<EntryVm>(entry);
}
}
}

View File

@@ -21,7 +21,7 @@ namespace ModernKeePass.Application.Entry.Models
public string Notes { get; set; }
public Uri Url { get; set; }
public Dictionary<string, string> AdditionalFields { get; set; }
public IEnumerable<EntryVm> History { get; set; }
public List<EntryVm> History { get; set; }
public Icon Icon { get; set; }
public Color ForegroundColor { get; set; }
public Color BackgroundColor { get; set; }

View File

@@ -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<UpdateGroupCommand>
{
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;
}
}
}
}

View File

@@ -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<EntryEntity>(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<EntryEntity>(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)

View File

@@ -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<IMediator>()) { }
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;
}
}
}

View File

@@ -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();

View File

@@ -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<GroupVm> Groups { get; }
public bool IsNotRoot => Database.RootGroupId != _group.Id;
public IOrderedEnumerable<IGrouping<char, EntryVm>> 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<GroupVm> BreadCrumb { get; }
public ICommand SaveCommand { get; }

View File

@@ -239,19 +239,16 @@
<userControls:TopMenuUserControl x:Name="TopMenu" Grid.Column="2"
SortButtonVisibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEditButtonChecked="{Binding IsEditMode, Mode=TwoWay}"
IsMoveButtonEnabled="{Binding IsNotRoot}"
IsDeleteButtonEnabled="{Binding IsNotRoot}"
SaveCommand="{Binding SaveCommand}"
MoveCommand="{Binding MoveCommand}"
SortEntriesCommand="{Binding SortEntriesCommand}"
SortGroupsCommand="{Binding SortGroupsCommand}">
SortGroupsCommand="{Binding SortGroupsCommand}"
DeleteButtonClick="TopMenu_OnDeleteButtonClick">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="EditButtonClick">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="DeleteButtonClick">
<actions:DeleteEntityAction Entity="{Binding}" Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="MoveButtonClick">
<core:InvokeCommandAction Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
<!--<actions:ToastAction x:Uid="RestoreGroupCommand" Title="{Binding Title}" />-->

View File

@@ -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
}
}

View File

@@ -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<Symbol> Symbols { get; }
public List<Symbol> Symbols { get; }
public Symbol SelectedSymbol
{
@@ -27,7 +28,12 @@ namespace ModernKeePass.Views.UserControls
public SymbolPickerUserControl()
{
InitializeComponent();
Symbols = Enum.GetValues(typeof(Symbol)).Cast<Symbol>();
Symbols = new List<Symbol>();
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)

View File

@@ -90,7 +90,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Actions\ClipboardAction.cs" />
<Compile Include="Actions\DeleteEntityAction.cs" />
<Compile Include="Actions\NavigateToUrlAction.cs" />
<Compile Include="Actions\SetupFocusAction.cs" />
<Compile Include="Actions\ToastAction.cs" />