Shipcalls now showing participant relevant info in correct columns

This commit is contained in:
Daniel Schick 2023-08-15 09:04:57 +02:00
parent 84462aead4
commit cf5498d049
10 changed files with 218 additions and 95 deletions

View File

@ -1,4 +1,5 @@
using System;
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
@ -13,5 +14,6 @@ namespace BreCalClient
/// </summary>
public partial class App : Application
{
public static Participant Participant { get; set; } = new Participant();
}
}

View File

@ -0,0 +1,62 @@
// Copyright (c) 2023 schick Informatik
// Description: some helpers
//
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BreCalClient
{
internal static class Extensions
{
#region Enum
/// <summary>
/// Copied from models clunky I know
/// </summary>
[Flags]
public enum ParticipantType
{
[Description("not assigned")]
NONE = 0,
[Description("BSMD")]
BSMD = 1,
[Description("Terminal")]
TERMINAL = 2,
[Description("Lotsen")]
PILOT = 4,
[Description("Agentur")]
AGENCY = 8,
[Description("Festmacher")]
MOORING = 16,
[Description("Hafenamt")]
PORT_ADMINISTRATION = 32,
[Description("Schlepper")]
TUG = 64,
}
#endregion
#region public helper
public static bool IsFlagSet(this Participant participant, ParticipantType flag)
{
return (participant.Type & (uint)flag) != 0;
}
public static void SetFlag(this Participant participant, bool value, ParticipantType flag)
{
if (value) participant.Type |= (int)flag;
else participant.Type &= (int)~flag;
}
#endregion
}
}

View File

@ -57,6 +57,7 @@
<ColumnDefinition Width=".2*" />
<ColumnDefinition Width=".6*" />
</Grid.ColumnDefinitions>
<Button Margin="2" Grid.Column="0" Content="{x:Static p:Resources.textNewDots}" x:Name="buttonNew" Visibility="Hidden" />
<Label Content="{x:Static p:Resources.textSortOrder}" Grid.Column="1" />
<ComboBox x:Name="comboBoxSortOrder" Margin="2" Grid.Column="2" />
</Grid>

View File

@ -22,15 +22,17 @@ namespace BreCalClient
public partial class MainWindow : Window
{
private const int SHIPCALL_UPDATE_INTERVAL_SECONDS = 30;
private DefaultApi _api;
private ObservableCollection<ShipcallControlModel> _controlModels = new();
private readonly DefaultApi _api;
private readonly ObservableCollection<ShipcallControlModel> _controlModels = new();
private List<Ship> _ships = new();
private ConcurrentDictionary<int, Ship> _shipLookupDict = new();
private readonly ConcurrentDictionary<int, Ship> _shipLookupDict = new();
private List<Berth> _berths = new();
private ConcurrentDictionary<int, Berth> _berthLookupDict = new();
private readonly ConcurrentDictionary<int, Berth> _berthLookupDict = new();
private List<Participant> _participants = new();
private Dictionary<int, Participant> _participantLookupDict = new();
private CancellationTokenSource _tokenSource = new CancellationTokenSource();
private readonly Dictionary<int, Participant> _participantLookupDict = new();
private readonly Dictionary<int, ShipcallControl> _shipCallControlDict = new();
private readonly CancellationTokenSource _tokenSource = new();
private LoginResult? _loginResult;
public MainWindow()
{
@ -64,13 +66,13 @@ namespace BreCalClient
try
{
LoginResult loginResult = await _api.LoginPostAsync(credentials);
if(loginResult != null)
_loginResult = await _api.LoginPostAsync(credentials);
if(_loginResult != null)
{
if(loginResult.Id > 0)
if(_loginResult.Id > 0)
{
this.busyIndicator.IsBusy = false;
this._api.Configuration.ApiKey["Authorization"] = loginResult.Token;
this._api.Configuration.ApiKey["Authorization"] = _loginResult.Token;
this.LoadStaticLists();
}
}
@ -104,79 +106,95 @@ namespace BreCalClient
foreach(var ship in this._ships)
_shipLookupDict[ship.Id] = ship;
this._participants = await _api.ParticipantsGetAsync();
List<Participant> agencies = new List<Participant>();
foreach (Participant participant in this._participants)
{
this._participantLookupDict[participant.Id] = participant;
if (_loginResult?.ParticipantId == participant.Id)
{
App.Participant = participant;
EnableControlsForParticipant();
}
}
_ = Task.Run(() => RefreshShipcalls());
}
private void EnableControlsForParticipant()
{
if (App.Participant.IsFlagSet(Extensions.ParticipantType.BSMD))
this.buttonNew.Visibility = Visibility.Visible;
}
public async Task RefreshShipcalls()
{
while (!_tokenSource.Token.IsCancellationRequested)
{
List<Shipcall> shipcalls = await _api.ShipcallsGetAsync();
foreach (Shipcall shipcall in shipcalls)
if (shipcalls != null)
{
ShipcallControlModel? selectedSCMModel = null;
foreach(ShipcallControlModel scm in this._controlModels)
foreach (Shipcall shipcall in shipcalls)
{
if(scm.Shipcall?.Id == shipcall.Id)
ShipcallControlModel? selectedSCMModel = null;
foreach (ShipcallControlModel scm in this._controlModels)
{
selectedSCMModel = scm;
break;
if (scm.Shipcall?.Id == shipcall.Id)
{
selectedSCMModel = scm;
break;
}
}
if (selectedSCMModel != null)
{
selectedSCMModel.Shipcall = shipcall;
}
else
{
// no: create new entry
selectedSCMModel = new ShipcallControlModel();
selectedSCMModel.Shipcall = shipcall;
if (this._shipLookupDict.ContainsKey(shipcall.ShipId))
selectedSCMModel.Ship = this._shipLookupDict[shipcall.ShipId];
if (this._berthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
selectedSCMModel.Berth = this._berthLookupDict[shipcall.ArrivalBerthId ?? 0].Name1;
_controlModels.Add(selectedSCMModel);
this.Dispatcher.Invoke(new Action(() =>
{
ShipcallControl sc = new ShipcallControl();
sc.Height = 120;
sc.ShipcallControlModel = selectedSCMModel;
sc.TimesRequested += Sc_TimesRequested;
sc.EditRequested += Sc_EditRequested;
this.stackPanel.Children.Add(sc);
this._shipCallControlDict[shipcall.Id] = sc;
}));
}
selectedSCMModel.AssignParticipants(this._participants);
this.Dispatcher.Invoke((Action)(() =>
{
this._shipCallControlDict[shipcall.Id].RefreshData();
}));
}
List<ShipcallControl> removeList = new();
foreach (ShipcallControlModel scm in this._controlModels)
{
if (shipcalls.Find(s => s.Id == scm.Shipcall?.Id) == null) // the model is no longer in the search result
{
if((scm.Shipcall != null) && this._shipCallControlDict.ContainsKey(scm.Shipcall.Id))
{
this.Dispatcher.Invoke((Action)(() =>
{
this.stackPanel.Children.Remove(this._shipCallControlDict[scm.Shipcall.Id]);
}));
this._shipCallControlDict.Remove(scm.Shipcall.Id);
}
}
}
if(selectedSCMModel != null)
{
selectedSCMModel.Shipcall = shipcall;
}
else
{
// no: create new entry
selectedSCMModel = new ShipcallControlModel();
selectedSCMModel.Shipcall = shipcall;
if (this._shipLookupDict.ContainsKey(shipcall.ShipId))
selectedSCMModel.Ship = this._shipLookupDict[shipcall.ShipId];
if (this._berthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
selectedSCMModel.Berth = this._berthLookupDict[shipcall.ArrivalBerthId ?? 0].Name1;
_controlModels.Add(selectedSCMModel);
this.Dispatcher.Invoke(new Action(() =>
{
ShipcallControl sc = new ShipcallControl();
sc.Height = 120;
sc.ShipcallControlModel = selectedSCMModel;
sc.TimesRequested += Sc_TimesRequested;
sc.EditRequested += Sc_EditRequested;
this.stackPanel.Children.Add(sc);
}));
}
selectedSCMModel.AssignParticipants(this._participants);
}
List<ShipcallControl> removeList = new();
foreach (ShipcallControlModel scm in this._controlModels)
{
if(shipcalls.Find(s => s.Id == scm.Shipcall?.Id) == null)
{
foreach (ShipcallControl sc in this.stackPanel.Children)
if (sc.ShipcallControlModel?.Shipcall?.Id == scm.Shipcall?.Id)
removeList.Add(sc);
}
}
foreach(ShipcallControl sc in removeList)
{
this.Dispatcher.Invoke(new Action(() =>
{
this.stackPanel.Children.Remove(sc);
}));
}
await Task.Delay(TimeSpan.FromSeconds(SHIPCALL_UPDATE_INTERVAL_SECONDS), _tokenSource.Token);

View File

@ -278,6 +278,15 @@ namespace BreCalClient.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to New...
/// </summary>
public static string textNewDots {
get {
return ResourceManager.GetString("textNewDots", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Password.
/// </summary>

View File

@ -181,6 +181,9 @@
<data name="textLogin" xml:space="preserve">
<value>Anmelden</value>
</data>
<data name="textNewDots" xml:space="preserve">
<value>Neu..</value>
</data>
<data name="textPassword" xml:space="preserve">
<value>Passwort</value>
</data>

View File

@ -187,6 +187,9 @@
<data name="textLogin" xml:space="preserve">
<value>Login</value>
</data>
<data name="textNewDots" xml:space="preserve">
<value>New..</value>
</data>
<data name="textPassword" xml:space="preserve">
<value>Password</value>
</data>

View File

@ -89,17 +89,17 @@
</Grid>
<Label Grid.Row="0" Grid.Column="1" Grid.RowSpan="1" FontSize="10" Content="Agent" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<Label Grid.Row="0" Grid.Column="1" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelAgent"/>
<Label Grid.Row="0" Grid.Column="2" Grid.RowSpan="1" FontSize="10" Content="Mooring" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<Label Grid.Row="0" Grid.Column="2" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelMooring"/>
<Label Grid.Row="0" Grid.Column="3" Grid.RowSpan="1" FontSize="10" Content="Port authority" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<Label Grid.Row="0" Grid.Column="3" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPortAuthority"/>
<Label Grid.Row="0" Grid.Column="4" Grid.RowSpan="1" FontSize="10" Content="Pilot" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<Label Grid.Row="0" Grid.Column="4" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPilot"/>
<Label Grid.Row="0" Grid.Column="5" Grid.RowSpan="1" FontSize="10" Content="Tug" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<Label Grid.Row="0" Grid.Column="5" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTug"/>
<Label Grid.Row="0" Grid.Column="6" Grid.RowSpan="1" FontSize="10" Content="Terminal" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
<Label Grid.Row="0" Grid.Column="6" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="#203864" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTerminal"/>

View File

@ -42,14 +42,39 @@ namespace BreCalClient
#endregion
#region public methods
public void RefreshData()
{
if (this.ShipcallControlModel == null) return;
string? name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.AGENCY);
if (name != null)
this.labelAgent.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.MOORING);
if (name != null)
this.labelMooring.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.PILOT);
if (name != null)
this.labelPilot.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.TUG);
if (name != null)
this.labelTug.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.PORT_ADMINISTRATION);
if (name != null)
this.labelPortAuthority.Content = name;
name = this.ShipcallControlModel.GetParticipantNameForType(Extensions.ParticipantType.TERMINAL);
if (name != null)
this.labelTerminal.Content = name;
}
#endregion
#region event handler
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = this.ShipcallControlModel;
if (this.ShipcallControlModel == null) return;
this.labelAgent.Content = this.ShipcallControlModel.AssignedParticipants.ContainsKey(8) ? this.ShipcallControlModel.AssignedParticipants[8].Name : string.Empty;
this.labelMooring.Content = this.ShipcallControlModel.AssignedParticipants.ContainsKey(16) ? this.ShipcallControlModel.AssignedParticipants[16].Name : string.Empty;
this.DataContext = this.ShipcallControlModel;
}
private void buttonListTimes_Click(object sender, RoutedEventArgs e)
@ -80,20 +105,3 @@ namespace BreCalClient
}
}
/*
* Description("not assigned")]
NONE = 0,
[Description("BSMD")]
BSMD = 1,
[Description("Terminal")]
TERMINAL = 2,
[Description("Lotsen")]
PILOT = 4,
[Description("Agentur")]
AGENCY = 8,
[Description("Festmacher")]
MOORING = 16,
[Description("Hafenamt")]
PORT_ADMINISTRATION = 32,
[Description("Schlepper")]
TUG = 64,*/

View File

@ -2,9 +2,12 @@
// Description: Container model for shipcall related info
//
using BreCalClient.misc.Client;
using BreCalClient.misc.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace BreCalClient
{
@ -15,6 +18,8 @@ namespace BreCalClient
public class ShipcallControlModel
{
#region Enumerations
public enum TrafficLightMode
{
OFF,
@ -33,7 +38,9 @@ namespace BreCalClient
YELLOW,
BLINK_1,
BLINK_2
};
};
#endregion
public Shipcall? Shipcall { get; set; }
public Ship? Ship { get; set; }
@ -84,6 +91,16 @@ namespace BreCalClient
}
}
internal string? GetParticipantNameForType(Extensions.ParticipantType participantType)
{
foreach(Participant p in AssignedParticipants.Values)
{
if (p.IsFlagSet(participantType))
return p.Name;
}
return null;
}
#region private helper
private bool IsFlagSet(StatusFlags flag)
@ -92,7 +109,7 @@ namespace BreCalClient
return (this.Shipcall.Flags & (int) flag) != 0;
}
#endregion
#endregion
}
}