This repository has been archived on 2025-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
BreCal/src/RoleEditor/MainWindow.xaml.cs

609 lines
22 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using brecal.model;
using brecal.mysql;
namespace RoleEditor
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
#region private fields
private readonly ObservableCollection<Participant> _participants = new ObservableCollection<Participant>();
private readonly ObservableCollection<Role> _roles = new ObservableCollection<Role>();
private readonly ObservableCollection<Securable> _securables = new ObservableCollection<Securable>();
private readonly ObservableCollection<User> _users = new ObservableCollection<User>();
private readonly ObservableCollection<RoleAssignment> _assignedRoles = new ObservableCollection<RoleAssignment>();
private readonly ObservableCollection<SecurableAssignment> _assignedSecurables = new ObservableCollection<SecurableAssignment>();
private readonly ObservableCollection<Berth> _berths = new ObservableCollection<Berth>();
private readonly ObservableCollection<Ship> _ships = new ObservableCollection<Ship>();
private DBManager _dbManager;
#endregion
#region Construction / Loading
public MainWindow()
{
InitializeComponent();
_dbManager = new();
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
// try database connection
try
{
// load all participants
List<Participant> participants = await Participant.LoadAll(_dbManager);
foreach(Participant p in participants)
_participants.Add(p);
this.listBoxParticipant.ItemsSource = _participants;
// load all roles
foreach(Role r in await Role.LoadAll(_dbManager))
_roles.Add(r);
this.listBoxRoles.ItemsSource = _roles;
// load all securables
foreach(Securable s in await Securable.LoadAll(_dbManager))
_securables.Add(s);
this.listBoxSecurables.ItemsSource = _securables;
// load all berths
foreach (Berth b in await Berth.LoadAll(_dbManager))
{
_berths.Add(b);
if(b.Participant_Id != null)
{
b.Participant = participants.Where( p => p.Id== b.Participant_Id ).FirstOrDefault();
}
}
this.dataGridBerths.Initialize();
this.dataGridBerths.ItemsSource = _berths;
this.dataGridBerths.CreateRequested += DataGridBerths_CreateRequested;
this.dataGridBerths.EditRequested += DataGridBerths_EditRequested;
this.dataGridBerths.DeleteRequested += DataGridBerths_DeleteRequested;
// load all ships
foreach (Ship s in await Ship.LoadAll(_dbManager))
{
_ships.Add(s);
if(s.Participant_Id != null)
{
s.Participant = participants.Where( p => p.Id == s.Participant_Id ).FirstOrDefault();
}
}
this.dataGridShips.Initialize();
this.dataGridShips.ItemsSource = _ships;
this.dataGridShips.CreateRequested += DataGridShips_CreateRequested;
this.dataGridShips.EditRequested += DataGridShips_EditRequested;
this.dataGridShips.DeleteRequested += DataGridShips_DeleteRequested;
// set other item sources (filled later after selection)
this.listBoxUser.ItemsSource = _users;
this.listBoxRoleSecurables.ItemsSource = _assignedSecurables;
this.listBoxUserRoles.ItemsSource = _assignedRoles;
this.comboBoxParticipantType.ItemsSource = EnumHelper.GetAllValuesAndDescription(typeof(Participant.ParticipantType));
}
catch (Exception ex)
{
MessageBox.Show($"Database connection couldn't be established: {ex.Message}");
this.Close();
}
}
#region ship context menu callbacks
private void DataGridShips_DeleteRequested(DbEntity obj)
{
if(obj is Ship s)
this._ships.Remove(s);
}
private async void DataGridShips_EditRequested(DbEntity obj)
{
if(obj is Ship s)
{
EditShipDialog esd = new();
esd.Ship = s;
esd.Participants.AddRange(this._participants);
if (esd.ShowDialog() ?? false)
{
await s.Save(_dbManager);
this.dataGridShips.ItemsSource = null;
this.dataGridShips.ItemsSource = _ships;
}
}
}
private async void DataGridShips_CreateRequested()
{
Ship s = new();
EditShipDialog esd = new();
esd.Ship = s;
esd.Participants.AddRange(this._participants);
if(esd.ShowDialog() ?? false)
{
_ships.Add(s);
await s.Save(_dbManager);
this.dataGridShips.ItemsSource = null;
this.dataGridShips.ItemsSource = _ships;
}
}
#endregion
#region berth context menu callbacks
private void DataGridBerths_DeleteRequested(DbEntity obj)
{
if(obj is Berth b)
this._berths.Remove(b);
}
private async void DataGridBerths_EditRequested(DbEntity obj)
{
if(obj is Berth b)
{
EditBerthDialog ebd = new();
ebd.Berth = b;
ebd.Participants.AddRange(this._participants);
if (ebd.ShowDialog() ?? false)
{
await b.Save(_dbManager);
this.dataGridBerths.ItemsSource = null; // extreme stupidity for me not wanting to implement INotifyPropertyChanged
this.dataGridBerths.ItemsSource = _berths;
}
}
}
private async void DataGridBerths_CreateRequested()
{
Berth b = new();
EditBerthDialog ebd = new();
ebd.Berth = b;
ebd.Participants.AddRange(this._participants);
if (ebd.ShowDialog() ?? false)
{
_berths.Add(b);
await b.Save(_dbManager);
this.dataGridBerths.ItemsSource = null;
this.dataGridBerths.ItemsSource = _berths;
}
}
#endregion
#endregion
#region button callbacks
private async void buttonParticipantSave_Click(object sender, RoutedEventArgs e)
{
Participant? p = this.listBoxParticipant.SelectedItem as Participant;
if (p != null)
{
p.Name = this.textBoxParticipantName.Text.Trim();
p.Street = this.textBoxParticipantStreet.Text.Trim();
p.PostalCode = this.textBoxParticipantPostalCode.Text.Trim();
p.City = this.textBoxParticipantCity.Text.Trim();
p.Type = 0;
for(int i = 0; i < this.comboBoxParticipantType?.SelectedItems.Count; i++)
{
object? v = this.comboBoxParticipantType?.SelectedItems[i];
if (v != null)
{
KeyValuePair<string, string> kvp = (KeyValuePair<string, string>)v;
Participant.ParticipantType pType = (Participant.ParticipantType)Enum.Parse(typeof(Participant.ParticipantType), kvp.Key);
p.SetFlag(true, pType);
}
}
await p.Save(_dbManager);
this.listBoxParticipant.ItemsSource = null;
this.listBoxParticipant.ItemsSource = _participants;
this.listBoxParticipant.SelectedItem = p;
}
}
private async void buttonUserSave_Click(object sender, RoutedEventArgs e)
{
User? u = this.listBoxUser.SelectedItem as User;
if(u != null)
{
u.Firstname = this.textBoxUserFirstName.Text.Trim();
u.Lastname = this.textBoxUserLastName.Text.Trim();
u.Username = this.textBoxUserUserName.Text.Trim();
if(this.textBoxUserPassword.Text.Trim().Length > 0 )
{
string passwortText = this.textBoxUserPassword.Text.Trim();
byte[] bytes = Encoding.Default.GetBytes(passwortText);
passwortText = Encoding.UTF8.GetString(bytes);
// Das sollte nicht verändert werden um kompatibel zu der Python Implementierung zu bleiben
string salt = BCrypt.Net.BCrypt.GenerateSalt(12, 'b');
u.PasswordHash = BCrypt.Net.BCrypt.HashPassword(passwortText, salt);
}
u.APIKey = this.textBoxUserAPIKey.Text.Trim();
await u.Save(_dbManager);
this.listBoxUser.ItemsSource = null;
this.listBoxUser.ItemsSource = _users;
this.listBoxUser.SelectedItem = u;
}
}
private async void buttonAddRole_Click(object sender, RoutedEventArgs e)
{
Role? r = this.listBoxRoles.SelectedItem as Role;
User? u = this.listBoxUser.SelectedItem as User;
if((r != null) && (u != null))
{
// test if assignment is already present
bool foundMatchingAssignment = false;
foreach(RoleAssignment ra in _assignedRoles)
{
if((ra.UserId == u.Id) && (ra.RoleId == r.Id))
{
foundMatchingAssignment = true;
break;
}
}
if(!foundMatchingAssignment)
{
RoleAssignment ra = new RoleAssignment();
ra.UserId = (int) u.Id;
ra.RoleId = (int) r.Id;
ra.AssignedRole = r;
ra.AssignedUser = u;
await ra.Save(_dbManager);
_assignedRoles.Add(ra);
}
}
}
private async void buttonRemoveRole_Click(object sender, RoutedEventArgs e)
{
// remove role from user
RoleAssignment? ra = this.listBoxUserRoles.SelectedItem as RoleAssignment;
if(ra != null)
{
await ra.Delete(_dbManager);
if(_assignedRoles.Contains(ra))
_assignedRoles.Remove(ra);
}
}
private async void buttonAddSecurable_Click(object sender, RoutedEventArgs e)
{
if ((this.listBoxRoles.SelectedItem is Role r) && (this.listBoxSecurables.SelectedItem is Securable s))
{
// test if assignment is already present
bool foundMatchingAssignment = false;
foreach (SecurableAssignment sa in _assignedSecurables)
{
if ((sa.SecurableId == s.Id) && (sa.RoleId == r.Id))
{
foundMatchingAssignment = true;
break;
}
}
if (!foundMatchingAssignment)
{
SecurableAssignment sa = new SecurableAssignment();
sa.SecurableId = (int)s.Id;
sa.RoleId = (int)r.Id;
sa.AssignedRole = r;
sa.AssignedSecurable = s;
await sa.Save(_dbManager);
_assignedSecurables.Add(sa);
}
}
}
private async void buttonRemoveSecurable_Click(object sender, RoutedEventArgs e)
{
SecurableAssignment? sa = this.listBoxRoleSecurables.SelectedItem as SecurableAssignment;
if(sa != null)
{
await sa.Delete(_dbManager);
if (_assignedSecurables.Contains(sa))
_assignedSecurables.Remove(sa);
}
}
private async void buttonSaveSecurable_Click(object sender, RoutedEventArgs e)
{
Securable? s = this.listBoxSecurables.SelectedItem as Securable;
if(s != null)
{
s.Name = this.textBoxSecurableName.Text.Trim();
await s.Save(_dbManager);
this.listBoxSecurables.ItemsSource = null;
this.listBoxSecurables.ItemsSource = _securables;
this.listBoxSecurables.SelectedItem = s;
}
}
private async void buttonSaveRole_Click(object sender, RoutedEventArgs e)
{
Role? r = this.listBoxRoles.SelectedItem as Role;
if(r != null)
{
r.Name = this.textBoxRoleName.Text.Trim();
r.Description = this.textBoxRoleDescription.Text.Trim();
await r.Save(_dbManager);
this.listBoxRoles.ItemsSource = null;
this.listBoxRoles.ItemsSource = _roles;
this.listBoxRoles.SelectedItem = r;
}
}
#endregion
#region listbox selection callbacks
private async void listBoxParticipant_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Participant? p = this.listBoxParticipant.SelectedItem as Participant;
this.textBoxParticipantName.Text = (p != null) ? p.Name : string.Empty;
this.textBoxParticipantStreet.Text = (p != null) ? p.Street : string.Empty;
this.textBoxParticipantPostalCode.Text = (p != null) ? p.PostalCode : string.Empty;
this.textBoxParticipantCity.Text = (p != null) ? p.City : string.Empty;
// this.checkboxParticipantActive.Checked = (p != null) ? p.
this.textBoxParticipantCreated.Text = (p != null) ? p.Created.ToString() : string.Empty;
this.textBoxParticipantModified.Text = (p != null) ? p.Modified.ToString() : string.Empty;
this.comboBoxParticipantType.SelectedItems.Clear();
if (p != null)
{
foreach (Participant.ParticipantType pType in Enum.GetValues(typeof(Participant.ParticipantType)))
{
if (p.IsFlagSet(pType))
{
foreach (KeyValuePair<string, string> kvp in this.comboBoxParticipantType.Items)
{
if (kvp.Key.Equals(pType.ToString()))
{
this.comboBoxParticipantType.SelectedItems.Add(kvp);
}
}
}
}
}
// -> load users for this participant selection
this._users.Clear();
if (p != null)
{
foreach (User u in await User.LoadForParticipant(p, _dbManager))
_users.Add(u);
}
}
private async void listBoxRoles_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Role? r = this.listBoxRoles.SelectedItem as Role;
this.textBoxRoleName.Text = (r != null) ? r.Name : string.Empty;
this.textBoxRoleDescription.Text = (r != null) ? r.Description : string.Empty;
_assignedSecurables.Clear();
if (r != null)
{
// load assigned securables
foreach (SecurableAssignment sa in await SecurableAssignment.LoadForRole(r, _dbManager))
{
foreach (Securable s in this._securables)
{
if (sa.SecurableId == s.Id)
{
sa.AssignedSecurable = s;
break;
}
}
_assignedSecurables.Add(sa);
}
}
}
private async void listBoxUser_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
User? u = this.listBoxUser.SelectedItem as User;
this.textBoxUserFirstName.Text = (u != null) ? u.Firstname : string.Empty;
this.textBoxUserLastName.Text = (u != null) ? u.Lastname : string.Empty;
this.textBoxUserUserName.Text = (u != null) ? u.Username : string.Empty;
this.textBoxUserAPIKey.Text = (u != null) ? u.APIKey : string.Empty;
this.textBoxUserCreated.Text = (u != null) ? u.Created.ToString() : string.Empty;
this.textBoxUserModified.Text = (u != null) ? u.Modified.ToString() : string.Empty;
this.textBoxUserPassword.Text = string.Empty;
_assignedRoles.Clear();
if (u != null)
{
// load roles assigned to user
foreach (RoleAssignment ra in await RoleAssignment.LoadForUser(u, _dbManager))
{
foreach (Role r in this._roles)
{
if (ra.RoleId == r.Id)
{
ra.AssignedRole = r;
break;
}
}
_assignedRoles.Add(ra);
}
}
}
private void listBoxSecurables_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Securable? s = this.listBoxSecurables.SelectedItem as Securable;
this.textBoxSecurableName.Text = (s != null) ? s.Name : string.Empty;
}
#endregion
#region menuitem callbacks
private async void menuItemDeleteParticipant_Click(object sender, RoutedEventArgs e)
{
try
{
if(this.listBoxParticipant.SelectedItem is Participant p)
{
await p.Delete(_dbManager);
this._participants.Remove(p);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void menuItemNewParticipant_Click(object sender, RoutedEventArgs e)
{
Participant p = new();
this._participants.Add(p);
this.listBoxParticipant.SelectedItem = p;
}
private void menuItemNewUser_Click(object sender, RoutedEventArgs e)
{
Participant? p = this.listBoxParticipant.SelectedItem as Participant;
if(p != null)
{
User u = new();
u.Participant_Id = p.Id;
_users.Add(u);
this.listBoxUser.SelectedItem = u;
}
}
private async void menuItemDeleteUser_Click(object sender, RoutedEventArgs e)
{
try
{
if (this.listBoxUser.SelectedItem is User u)
{
await u.Delete(_dbManager);
this._users.Remove(u);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void menuItemNewRole_Click(object sender, RoutedEventArgs e)
{
Role r = new();
this._roles.Add(r);
this.listBoxRoles.SelectedItem = r;
}
private async void menuItemDeleteRole_Click(object sender, RoutedEventArgs e)
{
try
{
if (this.listBoxRoles.SelectedItem is Role r)
{
await r.Delete(_dbManager);
this._roles.Remove(r);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void menuItemNewSecurable_Click(object sender, RoutedEventArgs e)
{
Securable s = new Securable();
_securables.Add(s);
this.listBoxSecurables.SelectedItem = s;
}
private async void menuItemDeleteSecurable_Click(object sender, RoutedEventArgs e)
{
try
{
if (this.listBoxSecurables.SelectedItem is Securable s)
{
await s.Delete(_dbManager);
this._securables.Remove(s);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
#endregion
#region Excel import
private void buttonImportBerths_Click(object sender, RoutedEventArgs e)
{
}
private void buttonImportShipss_Click(object sender, RoutedEventArgs e)
{
}
#endregion
#region private static helper
private static BitmapImage? LoadImage(byte[] imageData)
{
if (imageData == null || imageData.Length == 0) return null;
var image = new BitmapImage();
using (var mem = new MemoryStream(imageData))
{
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
#endregion
}
}