Merge branch 'bugfix/deactivating_users_roleeditor' into develop

This commit is contained in:
Daniel Schick 2025-12-05 16:00:45 +01:00
commit a50cd9cc9a
10 changed files with 68 additions and 22 deletions

View File

@ -39,6 +39,25 @@ CREATE TABLE `berth` (
) ENGINE=InnoDB AUTO_INCREMENT=195 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Berth of ship for a ship call'; ) ENGINE=InnoDB AUTO_INCREMENT=195 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Berth of ship for a ship call';
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
CREATE TABLE `history` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`participant_id` int unsigned NOT NULL,
`user_id` int unsigned DEFAULT NULL,
`shipcall_id` int unsigned NOT NULL,
`timestamp` datetime NOT NULL COMMENT 'Time of saving',
`eta` datetime DEFAULT NULL COMMENT 'Current ETA / ETD value (depends if shipcall or times were saved)',
`type` int NOT NULL COMMENT 'shipcall or times',
`operation` int NOT NULL COMMENT 'insert, update or delete',
PRIMARY KEY (`id`),
KEY `FK_HISTORY_PARTICIPANT_idx` (`participant_id`),
KEY `FK_HISTORY_SHIPCALL_idx` (`shipcall_id`),
KEY `FK_HISTORY_USER` (`user_id`),
CONSTRAINT `FK_HISTORY_PARTICIPANT` FOREIGN KEY (`participant_id`) REFERENCES `participant` (`id`),
CONSTRAINT `FK_HISTORY_SHIPCALL` FOREIGN KEY (`shipcall_id`) REFERENCES `shipcall` (`id`),
CONSTRAINT `FK_HISTORY_USER` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29292 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='This table stores a history of changes made to shipcalls so that everyone can see who changed what and when';
-- --
-- Table structure for table `notification` -- Table structure for table `notification`
-- --

View File

@ -8,7 +8,7 @@
<applicationSettings> <applicationSettings>
<RoleEditor.Properties.Settings> <RoleEditor.Properties.Settings>
<setting name="ConnectionString" serializeAs="String"> <setting name="ConnectionString" serializeAs="String">
<value>Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling_test;Port=33306</value> <value>Server=localhost;User ID=ds;Password=HalloWach_2323XXL!!;Database=bremen_calling_test;Port=33307</value>
</setting> </setting>
</RoleEditor.Properties.Settings> </RoleEditor.Properties.Settings>
</applicationSettings> </applicationSettings>

View File

@ -59,7 +59,7 @@
<Label Content="Street" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right"/> <Label Content="Street" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right"/>
<Label Content="Postal code" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right"/> <Label Content="Postal code" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right"/>
<Label Content="City" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right"/> <Label Content="City" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right"/>
<Label Content="Active" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Right"/> <Label Content="Deleted" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Right"/>
<Label Content="Type" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Right"/> <Label Content="Type" Grid.Row="5" Grid.Column="1" HorizontalAlignment="Right"/>
<Label Content="Created" Grid.Row="6" Grid.Column="1" HorizontalAlignment="Right"/> <Label Content="Created" Grid.Row="6" Grid.Column="1" HorizontalAlignment="Right"/>
<Label Content="Modified" Grid.Row="7" Grid.Column="1" HorizontalAlignment="Right"/> <Label Content="Modified" Grid.Row="7" Grid.Column="1" HorizontalAlignment="Right"/>
@ -67,7 +67,7 @@
<TextBox x:Name="textBoxParticipantStreet" Grid.Row="1" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxParticipantStreet" Grid.Row="1" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxParticipantPostalCode" Grid.Row="2" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxParticipantPostalCode" Grid.Row="2" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<TextBox x:Name="textBoxParticipantCity" Grid.Row="3" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxParticipantCity" Grid.Row="3" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<CheckBox x:Name="checkboxParticipantActive" Grid.Row="4" Grid.Column="2" VerticalAlignment="Center" /> <CheckBox x:Name="checkboxParticipantDeleted" Grid.Row="4" Grid.Column="2" VerticalAlignment="Center" IsEnabled="False" />
<xctk:CheckComboBox x:Name="comboBoxParticipantType" Grid.Row="5" Grid.Column="2" Margin="2" SelectedValue="Key" DisplayMemberPath="Value" /> <xctk:CheckComboBox x:Name="comboBoxParticipantType" Grid.Row="5" Grid.Column="2" Margin="2" SelectedValue="Key" DisplayMemberPath="Value" />
<TextBox x:Name="textBoxParticipantCreated" Grid.Row="6" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" /> <TextBox x:Name="textBoxParticipantCreated" Grid.Row="6" IsReadOnly="True" IsEnabled="False" Grid.Column="2" Margin="2" VerticalContentAlignment="Center" />
<StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="0"> <StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="0">
@ -167,7 +167,7 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ListBox x:Name="listBoxUser" Margin="2" Grid.RowSpan="9" SelectionChanged="listBoxUser_SelectionChanged"> <ListBox x:Name="listBoxUser" Margin="2" Grid.RowSpan="9" SelectionChanged="listBoxUser_SelectionChanged">
<ListBox.ContextMenu> <ListBox.ContextMenu>
<ContextMenu> <ContextMenu Name="contextMenuUser">
<MenuItem x:Name="menuItemNewUser" Header="New.." Click="menuItemNewUser_Click"> <MenuItem x:Name="menuItemNewUser" Header="New.." Click="menuItemNewUser_Click">
<MenuItem.Icon> <MenuItem.Icon>
<Image Source="Resources/add.png" /> <Image Source="Resources/add.png" />

View File

@ -61,6 +61,8 @@ namespace RoleEditor
// load all participants // load all participants
List<Participant> participants = await Participant.LoadAll(_dbManager); List<Participant> participants = await Participant.LoadAll(_dbManager);
participants.Sort((x, y) => string.Compare(x.Name, y.Name));
foreach (Participant p in participants) foreach (Participant p in participants)
{ {
_participants.Add(p); _participants.Add(p);
@ -464,9 +466,9 @@ namespace RoleEditor
this.textBoxParticipantName.Text = (p != null) ? p.Name : string.Empty; this.textBoxParticipantName.Text = (p != null) ? p.Name : string.Empty;
this.textBoxParticipantStreet.Text = (p != null) ? p.Street : string.Empty; this.textBoxParticipantStreet.Text = (p != null) ? p.Street : string.Empty;
this.textBoxParticipantPostalCode.Text = (p != null) ? p.PostalCode : string.Empty; this.textBoxParticipantPostalCode.Text = (p != null) ? p.PostalCode : string.Empty;
this.textBoxParticipantCity.Text = (p != null) ? p.City : 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.textBoxParticipantCreated.Text = (p != null) ? p.Created.ToString() : string.Empty;
this.checkboxParticipantDeleted.IsChecked = (p != null) ? p.Deleted : null;
this.textBoxParticipantModified.Text = (p != null) ? p.Modified.ToString() : string.Empty; this.textBoxParticipantModified.Text = (p != null) ? p.Modified.ToString() : string.Empty;
this.checkBoxParticipantAllowBSMD.IsChecked = (p != null) ? p.IsFlagSet(Participant.ParticipantFlags.ALLOW_BSMD) : null; this.checkBoxParticipantAllowBSMD.IsChecked = (p != null) ? p.IsFlagSet(Participant.ParticipantFlags.ALLOW_BSMD) : null;
this.comboBoxParticipantType.SelectedItems.Clear(); this.comboBoxParticipantType.SelectedItems.Clear();
@ -510,6 +512,11 @@ namespace RoleEditor
_assignedPorts.Add(pa); _assignedPorts.Add(pa);
} }
} }
this.contextMenuUser.IsEnabled = !p.Deleted;
this.buttonAddPortAssignment.IsEnabled = !p.Deleted;
this.buttonRemovePortAssignment.IsEnabled = !p.Deleted;
} }
private async void listBoxRoles_SelectionChanged(object sender, SelectionChangedEventArgs e) private async void listBoxRoles_SelectionChanged(object sender, SelectionChangedEventArgs e)
@ -594,7 +601,7 @@ namespace RoleEditor
if(this.listBoxParticipant.SelectedItem is Participant p) if(this.listBoxParticipant.SelectedItem is Participant p)
{ {
await p.Delete(_dbManager); await p.Delete(_dbManager);
this._participants.Remove(p); p.Deleted = true;
} }
} }
catch (Exception ex) catch (Exception ex)
@ -628,6 +635,7 @@ namespace RoleEditor
{ {
if (this.listBoxUser.SelectedItem is User u) if (this.listBoxUser.SelectedItem is User u)
{ {
await u.ExecuteNonQuery(_dbManager); // extra history delete happens here
await u.Delete(_dbManager); await u.Delete(_dbManager);
this._users.Remove(u); this._users.Remove(u);
} }

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<ApplicationIcon>Resources\lock_preferences.ico</ApplicationIcon> <ApplicationIcon>Resources\lock_preferences.ico</ApplicationIcon>
@ -30,8 +30,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" /> <PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="ExcelDataReader" Version="3.7.0-develop00385" /> <PackageReference Include="ExcelDataReader" Version="3.8.0" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.0" /> <PackageReference Include="Extended.Wpf.Toolkit" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,8 +1,4 @@
using System; using System.Data;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace brecal.model namespace brecal.model
@ -42,6 +38,11 @@ namespace brecal.model
/// <param name="cmd">CMD created by DB manager</param> /// <param name="cmd">CMD created by DB manager</param>
public abstract void SetDelete(IDbCommand cmd); public abstract void SetDelete(IDbCommand cmd);
public virtual void SetNonQuery(IDbCommand cmd)
{
// default: do nothing
}
/// <summary> /// <summary>
/// Each database entity must be able to save itself to the database /// Each database entity must be able to save itself to the database
/// </summary> /// </summary>
@ -61,9 +62,14 @@ namespace brecal.model
/// Each entity must be able to delete itself /// Each entity must be able to delete itself
/// </summary> /// </summary>
public async Task Delete(IDBManager manager) public async Task Delete(IDBManager manager)
{ {
await manager.ExecuteNonQuery(this.SetDelete); await manager.ExecuteNonQuery(this.SetDelete);
} }
public async Task ExecuteNonQuery(IDBManager manager)
{
await manager.ExecuteNonQuery(this.SetNonQuery);
}
} }
} }

View File

@ -55,6 +55,8 @@ namespace brecal.model
public uint Flags { get; set; } public uint Flags { get; set; }
public bool Deleted { get; set; } = false;
#endregion #endregion
#region public static methods #region public static methods
@ -83,6 +85,7 @@ namespace brecal.model
if (!reader.IsDBNull(6)) p.Flags = (uint)reader.GetInt32(6); if (!reader.IsDBNull(6)) p.Flags = (uint)reader.GetInt32(6);
if (!reader.IsDBNull(7)) p.Created = reader.GetDateTime(7); if (!reader.IsDBNull(7)) p.Created = reader.GetDateTime(7);
if (!reader.IsDBNull(8)) p.Modified = reader.GetDateTime(8); if (!reader.IsDBNull(8)) p.Modified = reader.GetDateTime(8);
if (!reader.IsDBNull(9)) p.Deleted = reader.GetBoolean(9);
result.Add(p); result.Add(p);
} }
return result; return result;
@ -90,7 +93,7 @@ namespace brecal.model
public static void SetLoadQuery(IDbCommand cmd, params object?[] list) public static void SetLoadQuery(IDbCommand cmd, params object?[] list)
{ {
cmd.CommandText = "SELECT id, name, street, postal_code, city, type, flags, created, modified FROM participant"; cmd.CommandText = "SELECT id, name, street, postal_code, city, type, flags, created, modified, deleted FROM participant";
} }
#endregion #endregion
@ -111,13 +114,13 @@ namespace brecal.model
public override void SetDelete(IDbCommand cmd) public override void SetDelete(IDbCommand cmd)
{ {
cmd.CommandText = "DELETE FROM participant WHERE id = @ID"; cmd.CommandText = "UPDATE participant SET deleted = 1 WHERE id = @ID";
IDataParameter idParam = cmd.CreateParameter(); IDataParameter idParam = cmd.CreateParameter();
idParam.ParameterName = "ID"; idParam.ParameterName = "ID";
idParam.Value = this.Id; idParam.Value = this.Id;
cmd.Parameters.Add(idParam); cmd.Parameters.Add(idParam);
} }
#endregion #endregion

View File

@ -101,6 +101,16 @@ namespace brecal.model
return this.Username ?? $"{base.Id} - {this.GetType().Name}"; return this.Username ?? $"{base.Id} - {this.GetType().Name}";
} }
public override void SetNonQuery(IDbCommand cmd)
{
cmd.CommandText = "UPDATE history set user_id = NULL WHERE user_id = @ID";
IDataParameter idParam = cmd.CreateParameter();
idParam.ParameterName = "ID";
idParam.Value = this.Id;
cmd.Parameters.Add(idParam);
}
#endregion #endregion
#region private methods #region private methods

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>

View File

@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MySqlConnector" Version="2.3.0-beta.1" /> <PackageReference Include="MySqlConnector" Version="2.4.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>