Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suche anbinden #11

Merged
merged 15 commits into from
Jul 20, 2024
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,5 @@ MigrationBackup/
.ionide/

# Fody - auto-generated XML schema
FodyWeavers.xsd
FodyWeavers.xsd
pwdb.scuml
3 changes: 3 additions & 0 deletions PWManager.Application/Services/GroupService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public List<string> GetAllGroupNames() {

public void SwitchGroup(string identifier) {
var group = _groupRepo.GetGroup(identifier);
if (group is null) {
return;
}
_environment.CurrentGroup = group;
}
}
37 changes: 28 additions & 9 deletions PWManager.Avalonia/Controls/AccountsControl.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,42 +1,61 @@
using Avalonia.Controls;
using PWManager.Application.Context;
using PWManager.Avalonia.Controls.BaseClass;
using PWManager.Avalonia.Models;
using PWManager.UI;
using PWManager.UI.Environment.Interfaces;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;

namespace PWManager.Avalonia.Controls;

public partial class AccountsControl : CustomControl {

public ObservableCollection<AccountDisplayModel> Accounts {get;set;}
private List<AccountDisplayModel> _allAccounts;

public List<AccountDisplayModel> Accounts {get;private set;}

public AccountDisplayModel? CurrentlyOpenedAccount {get;set;}

private TopLevel _window = null!;
private IStatusEnvironment _statusEnv;

public AccountsControl() {

Check warning on line 27 in PWManager.Avalonia/Controls/AccountsControl.axaml.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_allAccounts' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 27 in PWManager.Avalonia/Controls/AccountsControl.axaml.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Accounts' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
InitializeComponent();
this.DataContext = this;

this.SizeChanged += UpdateSize;

Accounts = new ObservableCollection<AccountDisplayModel>(new List<AccountDisplayModel> {
new AccountDisplayModel {AccountName = "TestAccount 1", LoginName = "account1", Password="pass1"},
new AccountDisplayModel {AccountName = "TestAccount 2", LoginName = "account2", Password="pass2"},
new AccountDisplayModel {AccountName = "TestAccount 3", LoginName = "account3", Password="pass3"},
});
_statusEnv = IoC.Resolve<IStatusEnvironment>();

OnPropertyChanged(nameof(Accounts));
_statusEnv.CurrentGroupUpdated += UpdateAccounts;
_statusEnv.AccountFilterUpdated += OnFilterUpdated;
UpdateAccounts();

this.Initialized += OnInit;
}

private void UpdateAccounts() {
if(_statusEnv.CurrentGroup is null) {
return;
}
_allAccounts = _statusEnv.CurrentGroup.Accounts.Select(e => new AccountDisplayModel {AccountName = e.Identifier, Password = e.Password, LoginName = e.LoginName}).ToList();

Accounts = _allAccounts;
OnPropertyChanged(nameof(Accounts));
}

private void OnFilterUpdated(string filter) {
Accounts = _allAccounts.Where(e => e.AccountName.ToLower().Contains(filter.ToLower())).ToList();
OnPropertyChanged(nameof(Accounts));
}

private void OnInit(object? sender, EventArgs e) {
Console.WriteLine("Here");
_window = TopLevel.GetTopLevel(this) ?? throw new ApplicationException("Window not found");
Console.WriteLine("Here!");
}

private void UpdateSize(object? sender, SizeChangedEventArgs e) {
Expand Down
2 changes: 1 addition & 1 deletion PWManager.Avalonia/Controls/SideNav.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<StackPanel HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Margin="0 0 5 0" FontSize="20">Groups</TextBlock>
<Button Classes="iconfont" FontSize="20">&#xF067;</Button>
<Button Command="{Binding OnAdd}" Classes="iconfont" FontSize="20">&#xF067;</Button>
</StackPanel>
<ItemsRepeater ItemsSource="{Binding AvailableGroups}" Margin="0 20 0 0">
<ItemsRepeater.ItemTemplate>
Expand Down
56 changes: 43 additions & 13 deletions PWManager.Avalonia/Controls/SideNav.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using PWManager.Application.Context;
using PWManager.Application.Services.Interfaces;
using PWManager.Avalonia.Controls.BaseClass;
using PWManager.Avalonia.Models;
using PWManager.UI;
using PWManager.UI.Environment.Interfaces;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
Expand All @@ -8,30 +12,56 @@
namespace PWManager.Avalonia.Controls;

public partial class SideNav : CustomControl {

public ObservableCollection<GroupDisplayModel> AvailableGroups { get; set; }

private readonly IStatusEnvironment _env;
private readonly IUserEnvironment _userEnv;
private readonly IGroupService _groupService;
public ObservableCollection<GroupDisplayModel> AvailableGroups { get; set; }

public SideNav() {
_env = IoC.Resolve<IStatusEnvironment>();
_userEnv = IoC.Resolve<IUserEnvironment>();
_groupService = IoC.Resolve<IGroupService>();
_env.CurrentGroupUpdated += OnCurrentGroupUpdate;

InitializeComponent();
DataContext = this;
InitializeDebugGroupDisplay();
InitializeGroupDisplay();
}

private void OnCurrentGroupUpdate() {
var currentGroup = _env.CurrentGroup?.Identifier!;

foreach (var group in AvailableGroups)
{
if (group.Identifier.Equals(currentGroup)) {
group.IsActiveGroup = true;
} else {
group.IsActiveGroup = false;
}
}
OnPropertyChanged(nameof(AvailableGroups));
}

private void InitializeDebugGroupDisplay() {
var groups = new GroupDisplayModel[] {
new() { Id = Guid.NewGuid().ToString(), Identifier = "main", IsMainGroup = true },
new() { Id = Guid.NewGuid().ToString(), Identifier = "finanzen", IsRemoteGroup = true },
new() { Id = Guid.NewGuid().ToString(), Identifier = "gamesaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" },
new() { Id = Guid.NewGuid().ToString(), Identifier = "ssh", IsRemoteGroup = true },
new() { Id = Guid.NewGuid().ToString(), Identifier = "uni", IsActiveGroup = true },
new() { Id = Guid.NewGuid().ToString(), Identifier = "website" }
};
private void InitializeGroupDisplay() {

var groups = _groupService.GetAllGroupNames();

AvailableGroups = new ObservableCollection<GroupDisplayModel>(
groups.OrderByDescending(e => e.IsMainGroup)
groups
.Select(e => new GroupDisplayModel { Identifier = e })
.OrderByDescending(e => e.IsMainGroup)
.ThenBy(e => e.Identifier)
.ToList()
);

OnCurrentGroupUpdate();
OnPropertyChanged(nameof(AvailableGroups));
}

public void OnAdd() {
var test = Guid.NewGuid().ToString();
_groupService.AddGroup(_userEnv.CurrentUser?.Id!, test);
AvailableGroups.Add(new GroupDisplayModel { Identifier = test });
}
}
2 changes: 1 addition & 1 deletion PWManager.Avalonia/Controls/StatusBar.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public partial class StatusBar : CustomControl {

public bool Synchronizing { get => _env.Synchronizing; set => _env.Synchronizing = value; }

public string CurrentGroup { get => _env.CurrentGroup; set => _env.CurrentGroup = value; }
public string CurrentGroup { get => _env.CurrentGroup?.Identifier!; }

public StatusBar() {
_env = IoC.Resolve<IStatusEnvironment>();
Expand Down
2 changes: 1 addition & 1 deletion PWManager.Avalonia/Controls/TopNav.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</StackPanel>

<!--<Panel Grid.Column="1" Width="200" /> -->
<TextBox DockPanel.Dock="Left" VerticalAlignment="Stretch" Margin="10 0" MaxWidth="400" Height="32" Watermark="Search...">
<TextBox x:Name="accountSearch" DockPanel.Dock="Left" VerticalAlignment="Stretch" Margin="10 0" MaxWidth="400" Height="32" Watermark="Search...">
<TextBox.InnerLeftContent>
<TextBlock Classes="iconfont" VerticalAlignment="Center" Padding="5 0">&#xF422;</TextBlock>
</TextBox.InnerLeftContent>
Expand Down
22 changes: 21 additions & 1 deletion PWManager.Avalonia/Controls/TopNav.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using PWManager.Avalonia.Controls.BaseClass;
using PWManager.UI;
using PWManager.UI.Environment.Interfaces;
using PWManager.UI.Extensions;
using System;

Expand All @@ -11,11 +15,27 @@ public partial class TopNav : CustomControl {
public event Action? AddAccountAction;
public event Action? SettingsAction;

private IStatusEnvironment _statusEnv;

public TopNav() {
InitializeComponent();

_statusEnv = IoC.Resolve<IStatusEnvironment>();

_statusEnv.CurrentGroupUpdated += ClearFilter;

accountSearch.KeyUp += UpdateFilter;

sidenavToggleButton.Click += (_,_) => ToggleNavAction?.SafeTrigger();
addButton.Click += (_,_) => AddAccountAction?.SafeTrigger();
settingsButton.Click += (_, _) => SettingsAction?.SafeTrigger();
}
}

private void UpdateFilter(object? sender, KeyEventArgs e) {
_statusEnv.OnAccountFilterUpdated(accountSearch.Text ?? string.Empty);
}

private void ClearFilter() {
accountSearch.Clear();
}
}
4 changes: 4 additions & 0 deletions PWManager.Avalonia/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using PWManager.Application.Context;
using PWManager.Avalonia.Environment;
using PWManager.UI.Environment.Interfaces;

Expand All @@ -10,6 +11,9 @@ public static IServiceCollection AddEnvironment(this IServiceCollection services
var env = new ApplicationEnvironment();

services.AddSingleton<IStatusEnvironment>(env);
services.AddSingleton<IUserEnvironment>(env);
services.AddSingleton<ICryptEnvironment>(env);
services.AddSingleton<ICliEnvironment>(env);

return services;
}
Expand Down
34 changes: 30 additions & 4 deletions PWManager.Avalonia/Environment/ApplicationEnvironment.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

using PWManager.Application.Context;
using PWManager.Domain.Entities;
using PWManager.UI.Environment.Interfaces;
using System;

namespace PWManager.Avalonia.Environment {
internal class ApplicationEnvironment : IStatusEnvironment {
internal class ApplicationEnvironment : IStatusEnvironment, IUserEnvironment, ICryptEnvironment, ICliEnvironment {

private bool _isConnected = false;
public bool Connected {
Expand All @@ -29,17 +31,41 @@ public bool Synchronizing {
}
}

private string _currentGroup = "main";
public string CurrentGroup {
private Group? _currentGroup;
public Group? CurrentGroup {
get => _currentGroup;
set {
if (_currentGroup == value) {
return;
}
_currentGroup = value;
StatusEnvironmentUpdated(nameof(CurrentGroup));
if (StatusEnvironmentUpdated is not null) {
StatusEnvironmentUpdated(nameof(CurrentGroup));
}
if (CurrentGroupUpdated is not null) {
CurrentGroupUpdated();
}
}
}

public User? CurrentUser { get; set ; }
public Settings? UserSettings { get; set; }
public string? EncryptionKey { get; set; }
public bool RunningSession { get; set; }

public event Action<string> StatusEnvironmentUpdated;
public event Action<string> UserEnvironmentUpdated;
public event Action<string> CryptEnvironmentUpdated;
public event Action CurrentGroupUpdated;
public event Action<string> AccountFilterUpdated;

public void WritePrompt() {
throw new NotImplementedException();
}

public void OnAccountFilterUpdated(string filtervalue)
{
AccountFilterUpdated?.Invoke(filtervalue);
}
}
}
34 changes: 29 additions & 5 deletions PWManager.Avalonia/Models/GroupDisplayModel.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
using System;
using PWManager.Application.Services.Interfaces;
using PWManager.UI;
using System;
using System.ComponentModel;

namespace PWManager.Avalonia.Models {
public class GroupDisplayModel {
public class GroupDisplayModel : INotifyPropertyChanged {

public string Id { get; set; } = string.Empty;
public string Identifier { get; set; } = string.Empty;

public bool IsMainGroup { get; set; }
public bool IsActiveGroup { get; set; }
private bool _isActiveGroup;
public bool IsActiveGroup { get => _isActiveGroup; set {
if (value == _isActiveGroup) {
return;
}
_isActiveGroup = value;
OnPropertyChanged(nameof(IsActiveGroup));
}
}
public bool IsRemoteGroup { get; set; }

public bool IsNormalGroup { get => !IsMainGroup && !IsRemoteGroup; }

public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public void OnClick() {
if (!IsActiveGroup) {
IoC.Resolve<IGroupService>().SwitchGroup(Identifier); // zu Event tauschen
}
}

public void OnDelete() {

// Event Triggern -> Name mit geben
// User PW abfrage
// ist das Main group? -> Ja -> neue Main group festlegen/erstellen
// -> Nein -> weiter
// zur main group wechseln
// Eintrag aus SideNav löschen
// Gruppe in DB löschen
}
}
}
11 changes: 7 additions & 4 deletions PWManager.Avalonia/Views/LoginView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlBackgroundAccentBrush}" />
</Style>
</Style>


<Style Selector="TextBox.empty">
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlBackgroundAccentBrush}" />
</Style>
</UserControl.Styles>

<Panel x:Name="container" Classes="stack-container">
Expand All @@ -59,13 +62,13 @@
<TextBlock Text="Login" FontSize="35" Margin="0 20" TextAlignment="Center"/>

<!-- Email box -->
<TextBox Text="{Binding UserName}" Tag="Username" Margin="0 0 0 10" Watermark="Username..."/>
<TextBox x:Name="nameBox" Text="{Binding UserName}" Tag="Username" Margin="0 0 0 10" Watermark="Username..."/>

<!-- Master Password Box -->
<TextBox PasswordChar="*" Tag="Password" Text="{Binding Password}" Margin="0 0 0 15" Watermark="Password..."/>
<TextBox x:Name="pwBox" PasswordChar="*" Tag="Password" Text="{Binding Password}" Margin="0 0 0 15" Watermark="Password..."/>

<!-- Button to login -->
<Button Classes="primary-btn" Content="Confirm" HorizontalAlignment="Center" Command="{Binding Login}"/>
<Button x:Name="loginBtn" Classes="primary-btn" Content="Confirm" HorizontalAlignment="Center" Command="{Binding Login}"/>
</StackPanel>
</Border>
</Panel>
Expand Down
Loading
Loading