diff --git a/misc/BreCalApi.cs b/misc/BreCalApi.cs
index b6cd9a2..833fdcd 100644
--- a/misc/BreCalApi.cs
+++ b/misc/BreCalApi.cs
@@ -1,8 +1,8 @@
//----------------------
//
-// Generated REST API Client Code Generator v1.7.17.0 on 05.09.2023 16:40:43
-// Using the tool OpenAPI Generator v6.6.0
+// Generated REST API Client Code Generator v1.8.4.0 on 11.09.2023 10:29:36
+// Using the tool OpenAPI Generator v7.0.0
//
//----------------------
@@ -29,7 +29,8 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
-using System.Net.Mime;
+
+using System.Net.Security;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
@@ -2334,7 +2335,6 @@ namespace BreCalClient.misc.Client
internal class CustomJsonCodec : IRestSerializer, ISerializer, IDeserializer
{
private readonly IReadableConfiguration _configuration;
- private static readonly string _contentType = "application/json";
private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
{
// OpenAPI generated types generally hide default constructors.
@@ -2435,15 +2435,11 @@ namespace BreCalClient.misc.Client
}
public ISerializer Serializer => this;
public IDeserializer Deserializer => this;
- public string[] AcceptedContentTypes => RestSharp.Serializers.ContentType.JsonAccept;
+ public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept;
public SupportsContentType SupportsContentType => contentType =>
- contentType.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) ||
- contentType.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase);
- public string ContentType
- {
- get { return _contentType; }
- set { throw new InvalidOperationException("Not allowed to set content type."); }
- }
+ contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) ||
+ contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase);
+ public ContentType ContentType { get; set; } = RestSharp.ContentType.Json;
public DataFormat DataFormat => DataFormat.Json;
}
///
@@ -2688,7 +2684,7 @@ namespace BreCalClient.misc.Client
}
return transformed;
}
- private ApiResponse Exec(RestRequest req, RequestOptions options, IReadableConfiguration configuration)
+ private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration)
{
var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl;
var cookies = new CookieContainer();
@@ -2705,84 +2701,87 @@ namespace BreCalClient.misc.Client
CookieContainer = cookies,
MaxTimeout = configuration.Timeout,
Proxy = configuration.Proxy,
- UserAgent = configuration.UserAgent
+ UserAgent = configuration.UserAgent,
+ UseDefaultCredentials = configuration.UseDefaultCredentials,
+ RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback
};
- RestClient client = new RestClient(clientOptions)
- .UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration));
- InterceptRequest(req);
- RestResponse response;
- if (RetryConfiguration.RetryPolicy != null)
+ using (RestClient client = new RestClient(clientOptions,
+ configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration))))
{
- var policy = RetryConfiguration.RetryPolicy;
- var policyResult = policy.ExecuteAndCapture(() => client.Execute(req));
- response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse
+ InterceptRequest(request);
+ RestResponse response;
+ if (RetryConfiguration.RetryPolicy != null)
{
- Request = req,
- ErrorException = policyResult.FinalException
- };
- }
- else
- {
- response = client.Execute(req);
- }
- // if the response type is oneOf/anyOf, call FromJSON to deserialize the data
- if (typeof(BreCalClient.misc.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
- {
- try
- {
- response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
- }
- catch (Exception ex)
- {
- throw ex.InnerException != null ? ex.InnerException : ex;
- }
- }
- else if (typeof(T).Name == "Stream") // for binary response
- {
- response.Data = (T)(object)new MemoryStream(response.RawBytes);
- }
- else if (typeof(T).Name == "Byte[]") // for byte response
- {
- response.Data = (T)(object)response.RawBytes;
- }
- else if (typeof(T).Name == "String") // for string response
- {
- response.Data = (T)(object)response.Content;
- }
- InterceptResponse(req, response);
- var result = ToApiResponse(response);
- if (response.ErrorMessage != null)
- {
- result.ErrorText = response.ErrorMessage;
- }
- if (response.Cookies != null && response.Cookies.Count > 0)
- {
- if (result.Cookies == null) result.Cookies = new List();
- foreach (var restResponseCookie in response.Cookies.Cast())
- {
- var cookie = new Cookie(
- restResponseCookie.Name,
- restResponseCookie.Value,
- restResponseCookie.Path,
- restResponseCookie.Domain
- )
+ var policy = RetryConfiguration.RetryPolicy;
+ var policyResult = policy.ExecuteAndCapture(() => client.Execute(request));
+ response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request)
{
- Comment = restResponseCookie.Comment,
- CommentUri = restResponseCookie.CommentUri,
- Discard = restResponseCookie.Discard,
- Expired = restResponseCookie.Expired,
- Expires = restResponseCookie.Expires,
- HttpOnly = restResponseCookie.HttpOnly,
- Port = restResponseCookie.Port,
- Secure = restResponseCookie.Secure,
- Version = restResponseCookie.Version
+ ErrorException = policyResult.FinalException
};
- result.Cookies.Add(cookie);
}
+ else
+ {
+ response = client.Execute(request);
+ }
+ // if the response type is oneOf/anyOf, call FromJSON to deserialize the data
+ if (typeof(BreCalClient.misc.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
+ {
+ try
+ {
+ response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
+ }
+ catch (Exception ex)
+ {
+ throw ex.InnerException != null ? ex.InnerException : ex;
+ }
+ }
+ else if (typeof(T).Name == "Stream") // for binary response
+ {
+ response.Data = (T)(object)new MemoryStream(response.RawBytes);
+ }
+ else if (typeof(T).Name == "Byte[]") // for byte response
+ {
+ response.Data = (T)(object)response.RawBytes;
+ }
+ else if (typeof(T).Name == "String") // for string response
+ {
+ response.Data = (T)(object)response.Content;
+ }
+ InterceptResponse(request, response);
+ var result = ToApiResponse(response);
+ if (response.ErrorMessage != null)
+ {
+ result.ErrorText = response.ErrorMessage;
+ }
+ if (response.Cookies != null && response.Cookies.Count > 0)
+ {
+ if (result.Cookies == null) result.Cookies = new List();
+ foreach (var restResponseCookie in response.Cookies.Cast())
+ {
+ var cookie = new Cookie(
+ restResponseCookie.Name,
+ restResponseCookie.Value,
+ restResponseCookie.Path,
+ restResponseCookie.Domain
+ )
+ {
+ Comment = restResponseCookie.Comment,
+ CommentUri = restResponseCookie.CommentUri,
+ Discard = restResponseCookie.Discard,
+ Expired = restResponseCookie.Expired,
+ Expires = restResponseCookie.Expires,
+ HttpOnly = restResponseCookie.HttpOnly,
+ Port = restResponseCookie.Port,
+ Secure = restResponseCookie.Secure,
+ Version = restResponseCookie.Version
+ };
+ result.Cookies.Add(cookie);
+ }
+ }
+ return result;
}
- return result;
}
- private async Task> ExecAsync(RestRequest req, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
+ private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken))
{
var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl;
var clientOptions = new RestClientOptions(baseUrl)
@@ -2790,71 +2789,73 @@ namespace BreCalClient.misc.Client
ClientCertificates = configuration.ClientCertificates,
MaxTimeout = configuration.Timeout,
Proxy = configuration.Proxy,
- UserAgent = configuration.UserAgent
+ UserAgent = configuration.UserAgent,
+ UseDefaultCredentials = configuration.UseDefaultCredentials
};
- RestClient client = new RestClient(clientOptions)
- .UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration));
- InterceptRequest(req);
- RestResponse response;
- if (RetryConfiguration.AsyncRetryPolicy != null)
+ using (RestClient client = new RestClient(clientOptions,
+ configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration))))
{
- var policy = RetryConfiguration.AsyncRetryPolicy;
- var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(req, ct), cancellationToken).ConfigureAwait(false);
- response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse
+ InterceptRequest(request);
+ RestResponse response;
+ if (RetryConfiguration.AsyncRetryPolicy != null)
{
- Request = req,
- ErrorException = policyResult.FinalException
- };
- }
- else
- {
- response = await client.ExecuteAsync(req, cancellationToken).ConfigureAwait(false);
- }
- // if the response type is oneOf/anyOf, call FromJSON to deserialize the data
- if (typeof(BreCalClient.misc.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
- {
- response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
- }
- else if (typeof(T).Name == "Stream") // for binary response
- {
- response.Data = (T)(object)new MemoryStream(response.RawBytes);
- }
- else if (typeof(T).Name == "Byte[]") // for byte response
- {
- response.Data = (T)(object)response.RawBytes;
- }
- InterceptResponse(req, response);
- var result = ToApiResponse(response);
- if (response.ErrorMessage != null)
- {
- result.ErrorText = response.ErrorMessage;
- }
- if (response.Cookies != null && response.Cookies.Count > 0)
- {
- if (result.Cookies == null) result.Cookies = new List();
- foreach (var restResponseCookie in response.Cookies.Cast())
- {
- var cookie = new Cookie(
- restResponseCookie.Name,
- restResponseCookie.Value,
- restResponseCookie.Path,
- restResponseCookie.Domain
- )
+ var policy = RetryConfiguration.AsyncRetryPolicy;
+ var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false);
+ response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request)
{
- Comment = restResponseCookie.Comment,
- CommentUri = restResponseCookie.CommentUri,
- Discard = restResponseCookie.Discard,
- Expired = restResponseCookie.Expired,
- Expires = restResponseCookie.Expires,
- HttpOnly = restResponseCookie.HttpOnly,
- Port = restResponseCookie.Port,
- Secure = restResponseCookie.Secure,
- Version = restResponseCookie.Version
+ ErrorException = policyResult.FinalException
};
- result.Cookies.Add(cookie);
}
+ else
+ {
+ response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
+ }
+ // if the response type is oneOf/anyOf, call FromJSON to deserialize the data
+ if (typeof(BreCalClient.misc.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T)))
+ {
+ response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content });
+ }
+ else if (typeof(T).Name == "Stream") // for binary response
+ {
+ response.Data = (T)(object)new MemoryStream(response.RawBytes);
+ }
+ else if (typeof(T).Name == "Byte[]") // for byte response
+ {
+ response.Data = (T)(object)response.RawBytes;
+ }
+ InterceptResponse(request, response);
+ var result = ToApiResponse(response);
+ if (response.ErrorMessage != null)
+ {
+ result.ErrorText = response.ErrorMessage;
+ }
+ if (response.Cookies != null && response.Cookies.Count > 0)
+ {
+ if (result.Cookies == null) result.Cookies = new List();
+ foreach (var restResponseCookie in response.Cookies.Cast())
+ {
+ var cookie = new Cookie(
+ restResponseCookie.Name,
+ restResponseCookie.Value,
+ restResponseCookie.Path,
+ restResponseCookie.Domain
+ )
+ {
+ Comment = restResponseCookie.Comment,
+ CommentUri = restResponseCookie.CommentUri,
+ Discard = restResponseCookie.Discard,
+ Expired = restResponseCookie.Expired,
+ Expires = restResponseCookie.Expires,
+ HttpOnly = restResponseCookie.HttpOnly,
+ Port = restResponseCookie.Port,
+ Secure = restResponseCookie.Secure,
+ Version = restResponseCookie.Version
+ };
+ result.Cookies.Add(cookie);
+ }
+ }
+ return result;
}
- return result;
}
#region IAsynchronousClient
///
@@ -3521,6 +3522,7 @@ namespace BreCalClient.misc.Client
/// Example: http://localhost:3000/v1/
///
private string _basePath;
+ private bool _useDefaultCredentials = false;
///
/// Gets or sets the API key based on the authentication name.
/// This is the key and value comprising the "secret" for accessing an API.
@@ -3610,11 +3612,20 @@ namespace BreCalClient.misc.Client
///
/// Gets or sets the base path for API access.
///
- public virtual string BasePath {
+ public virtual string BasePath
+ {
get { return _basePath; }
set { _basePath = value; }
}
///
+ /// Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) will be sent along to the server. The default is false.
+ ///
+ public virtual bool UseDefaultCredentials
+ {
+ get { return _useDefaultCredentials; }
+ set { _useDefaultCredentials = value; }
+ }
+ ///
/// Gets or sets the default header.
///
[Obsolete("Use DefaultHeaders instead.")]
@@ -3854,7 +3865,7 @@ namespace BreCalClient.misc.Client
/// The operation server URL.
public string GetOperationServerUrl(string operation, int index, Dictionary inputVariables)
{
- if (OperationServers.TryGetValue(operation, out var operationServer))
+ if (operation != null && OperationServers.TryGetValue(operation, out var operationServer))
{
return GetServerUrl(operationServer, index, inputVariables);
}
@@ -3905,6 +3916,10 @@ namespace BreCalClient.misc.Client
}
return url;
}
+ ///
+ /// Gets and Sets the RemoteCertificateValidationCallback
+ ///
+ public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
#endregion Properties
#region Methods
///
@@ -3970,6 +3985,8 @@ namespace BreCalClient.misc.Client
TempFolderPath = second.TempFolderPath ?? first.TempFolderPath,
DateTimeFormat = second.DateTimeFormat ?? first.DateTimeFormat,
ClientCertificates = second.ClientCertificates ?? first.ClientCertificates,
+ UseDefaultCredentials = second.UseDefaultCredentials,
+ RemoteCertificateValidationCallback = second.RemoteCertificateValidationCallback ?? first.RemoteCertificateValidationCallback,
};
return config;
}
@@ -4294,6 +4311,10 @@ namespace BreCalClient.misc.Client
/// Password.
string Password { get; }
///
+ /// Determine whether or not the "default credentials" (e.g. the user account under which the current process is running) will be sent along to the server. The default is false.
+ ///
+ bool UseDefaultCredentials { get; }
+ ///
/// Get the servers associated with the operation.
///
/// Operation servers.
@@ -4316,6 +4337,11 @@ namespace BreCalClient.misc.Client
///
/// X509 Certificate collection.
X509CertificateCollection ClientCertificates { get; }
+ ///
+ /// Callback function for handling the validation of remote certificates. Useful for certificate pinning and
+ /// overriding certificate errors in the scope of a request.
+ ///
+ RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; }
}
}
@@ -4877,16 +4903,16 @@ namespace BreCalClient.misc.Model
/// id.
/// name.
/// participantId.
- /// _lock.
+ /// varLock.
/// created.
/// modified.
/// deleted (default to false).
- public Berth(int id = default(int), string name = default(string), int? participantId = default(int?), bool? _lock = default(bool?), DateTime created = default(DateTime), DateTime? modified = default(DateTime?), bool deleted = false)
+ public Berth(int id = default(int), string name = default(string), int? participantId = default(int?), bool? varLock = default(bool?), DateTime created = default(DateTime), DateTime? modified = default(DateTime?), bool deleted = false)
{
this.Id = id;
this.Name = name;
this.ParticipantId = participantId;
- this.Lock = _lock;
+ this.VarLock = varLock;
this.Created = created;
this.Modified = modified;
this.Deleted = deleted;
@@ -4907,10 +4933,10 @@ namespace BreCalClient.misc.Model
[DataMember(Name = "participant_id", EmitDefaultValue = true)]
public int? ParticipantId { get; set; }
///
- /// Gets or Sets Lock
+ /// Gets or Sets VarLock
///
[DataMember(Name = "lock", EmitDefaultValue = true)]
- public bool? Lock { get; set; }
+ public bool? VarLock { get; set; }
///
/// Gets or Sets Created
///
@@ -4937,7 +4963,7 @@ namespace BreCalClient.misc.Model
sb.Append(" Id: ").Append(Id).Append("\n");
sb.Append(" Name: ").Append(Name).Append("\n");
sb.Append(" ParticipantId: ").Append(ParticipantId).Append("\n");
- sb.Append(" Lock: ").Append(Lock).Append("\n");
+ sb.Append(" VarLock: ").Append(VarLock).Append("\n");
sb.Append(" Created: ").Append(Created).Append("\n");
sb.Append(" Modified: ").Append(Modified).Append("\n");
sb.Append(" Deleted: ").Append(Deleted).Append("\n");
@@ -4988,9 +5014,9 @@ namespace BreCalClient.misc.Model
this.ParticipantId.Equals(input.ParticipantId))
) &&
(
- this.Lock == input.Lock ||
- (this.Lock != null &&
- this.Lock.Equals(input.Lock))
+ this.VarLock == input.VarLock ||
+ (this.VarLock != null &&
+ this.VarLock.Equals(input.VarLock))
) &&
(
this.Created == input.Created ||
@@ -5025,9 +5051,9 @@ namespace BreCalClient.misc.Model
{
hashCode = (hashCode * 59) + this.ParticipantId.GetHashCode();
}
- if (this.Lock != null)
+ if (this.VarLock != null)
{
- hashCode = (hashCode * 59) + this.Lock.GetHashCode();
+ hashCode = (hashCode * 59) + this.VarLock.GetHashCode();
}
if (this.Created != null)
{
@@ -6521,6 +6547,7 @@ namespace BreCalClient.misc.Model
///
/// Gets or Sets Participants
///
+ /// [1,5,7]
[DataMember(Name = "participants", EmitDefaultValue = true)]
public List Participants { get; set; }
///
diff --git a/src/BreCalClient/App.config b/src/BreCalClient/App.config
index 33176d0..5cb87a6 100644
--- a/src/BreCalClient/App.config
+++ b/src/BreCalClient/App.config
@@ -16,6 +16,9 @@
!!Bremen calling Testversion!!
+
+ https://www.textbausteine.net/
+
\ No newline at end of file
diff --git a/src/BreCalClient/BreCalClient.csproj b/src/BreCalClient/BreCalClient.csproj
index 1a919fa..3333e8e 100644
--- a/src/BreCalClient/BreCalClient.csproj
+++ b/src/BreCalClient/BreCalClient.csproj
@@ -95,12 +95,12 @@
-
+
-
-
+
+
diff --git a/src/BreCalClient/Extensions.cs b/src/BreCalClient/Extensions.cs
index b908fce..1a93d42 100644
--- a/src/BreCalClient/Extensions.cs
+++ b/src/BreCalClient/Extensions.cs
@@ -61,6 +61,13 @@ namespace BreCalClient
Shifting = 3
}
+ public enum SortOrder
+ {
+ SHIP_NAME,
+ ETA_ETD,
+ MODIFIED
+ }
+
#endregion
#region public helper
diff --git a/src/BreCalClient/MainWindow.xaml b/src/BreCalClient/MainWindow.xaml
index d03c01a..b87b972 100644
--- a/src/BreCalClient/MainWindow.xaml
+++ b/src/BreCalClient/MainWindow.xaml
@@ -58,11 +58,17 @@
-
+
+
+
+
-
+
+
+
+
diff --git a/src/BreCalClient/MainWindow.xaml.cs b/src/BreCalClient/MainWindow.xaml.cs
index b0357bb..c2bfb80 100644
--- a/src/BreCalClient/MainWindow.xaml.cs
+++ b/src/BreCalClient/MainWindow.xaml.cs
@@ -9,10 +9,12 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using static BreCalClient.Extensions;
namespace BreCalClient
{
@@ -22,22 +24,35 @@ namespace BreCalClient
public partial class MainWindow : Window
{
+ private const int SHIPCALL_UPDATE_INTERVAL_SECONDS = 30;
+
#region Fields
- private const int SHIPCALL_UPDATE_INTERVAL_SECONDS = 30;
- private readonly DefaultApi _api;
- private readonly ObservableCollection _controlModels = new();
+
+
+ private readonly Dictionary _allShipcallsDict = new();
+ private readonly Dictionary _allShipCallsControlDict = new();
+
+ private readonly List _visibleControlModels = new();
+
+
private List _ships = new();
private readonly ConcurrentDictionary _shipLookupDict = new();
private List _berths = new();
private readonly ConcurrentDictionary _berthLookupDict = new();
private List _participants = new();
private readonly Dictionary _participantLookupDict = new();
- private readonly Dictionary _shipCallControlDict = new();
+
+ private readonly DefaultApi _api;
private readonly CancellationTokenSource _tokenSource = new();
private LoginResult? _loginResult;
private bool _refreshImmediately = false;
+ private bool? _showCanceled = null;
+ private Extensions.SortOrder? _sortOrder;
+ private bool _filterChanged = false;
+ private bool _sequenceChanged = false;
+
#endregion
#region Enums
@@ -70,7 +85,13 @@ namespace BreCalClient
labelVersion.Text = "V. " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
if (!string.IsNullOrEmpty(Properties.Settings.Default.APP_TITLE))
this.Title = Properties.Settings.Default.APP_TITLE;
- }
+ searchFilterControl.SearchFilterChanged += SearchFilterControl_SearchFilterChanged;
+ searchFilterControl.LogoImageClicked += () =>
+ {
+ Process.Start("explorer", Properties.Settings.Default.LOGO_IMAGE_URL);
+ };
+ this.comboBoxSortOrder.ItemsSource = Enum.GetValues(typeof(Extensions.SortOrder));
+ }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
@@ -134,10 +155,13 @@ namespace BreCalClient
// create UI & save new dialog model
if (esc.ShipcallModel.Shipcall != null)
{
- this.UpdateShipcallUI(esc.ShipcallModel.Shipcall, new List());
- this._api.ShipcallsPost(esc.ShipcallModel.Shipcall);
- _refreshImmediately = true;
- _tokenSource.Cancel();
+ this.UpdateUI();
+
+ this._api.ShipcallsPost(esc.ShipcallModel.Shipcall); // save new ship call
+ this.AddShipcall(esc.ShipcallModel);
+
+ _refreshImmediately = true; // set flag to avoid timer loop termination
+ _tokenSource.Cancel(); // force timer loop end
}
}
}
@@ -175,9 +199,35 @@ namespace BreCalClient
ad.ShowDialog();
}
- #endregion
+ private void buttonClearFilter_Click(object sender, RoutedEventArgs e)
+ {
+ this.searchFilterControl.ClearFilters();
+ this.checkboxShowCancelledCalls.IsChecked = false;
+ this.FilterShipcalls();
+ }
- #region private methods
+ private void SearchFilterControl_SearchFilterChanged()
+ {
+ this.FilterShipcalls();
+ this.UpdateUI();
+ }
+
+ private void checkboxShowCancelledCalls_Checked(object sender, RoutedEventArgs e)
+ {
+ this._showCanceled = this.checkboxShowCancelledCalls.IsChecked;
+ this.SearchFilterControl_SearchFilterChanged();
+ }
+
+ private void comboBoxSortOrder_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
+ {
+ _sortOrder = (Extensions.SortOrder) this.comboBoxSortOrder.SelectedIndex;
+ this.FilterShipcalls();
+ this.UpdateUI();
+ }
+
+ #endregion
+
+ #region network operations
private async void LoadStaticLists()
{
@@ -205,13 +255,7 @@ namespace BreCalClient
this.searchFilterControl.SetAgencies(agencies);
_ = Task.Run(() => RefreshShipcalls());
- }
-
- private void EnableControlsForParticipant()
- {
- if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD))
- this.buttonNew.Visibility = Visibility.Visible;
- }
+ }
public async Task RefreshShipcalls()
{
@@ -236,30 +280,45 @@ namespace BreCalClient
labelStatusBar.Text = ex.Message;
}));
}
+
if (shipcalls != null)
{
foreach (Shipcall shipcall in shipcalls)
{
+ // load times for each shipcall
List currentTimes = await _api.TimesGetAsync(shipcall.Id);
- this.UpdateShipcallUI(shipcall, currentTimes);
- }
-
- List 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(!_allShipcallsDict.ContainsKey(shipcall.Id))
{
- if((scm.Shipcall != null) && this._shipCallControlDict.ContainsKey(scm.Shipcall.Id))
+ // add entry
+ ShipcallControlModel scm = new()
{
- this.Dispatcher.Invoke((Action)(() =>
- {
- this.stackPanel.Children.Remove(this._shipCallControlDict[scm.Shipcall.Id]);
- }));
- this._shipCallControlDict.Remove(scm.Shipcall.Id);
- }
+ Shipcall = shipcall,
+ Times = currentTimes
+ };
+ this.AddShipcall(scm);
+ }
+ else
+ {
+ // update entry
+ _allShipcallsDict[shipcall.Id].Shipcall = shipcall;
+ _allShipcallsDict[shipcall.Id].Times = currentTimes;
+ this.UpdateShipcall(_allShipcallsDict[shipcall.Id]);
+ }
+ }
+
+ List existingIds = new(this._allShipcallsDict.Keys);
+
+ foreach (int existingId in existingIds)
+ {
+ if (shipcalls.Find(s => s.Id == existingId) == null) // the model is no longer in the search result
+ {
+ this.RemoveShipcall(existingId);
}
}
+
+ this.FilterShipcalls();
+ this.UpdateUI();
}
try
@@ -270,60 +329,167 @@ namespace BreCalClient
}
}
- private void UpdateShipcallUI(Shipcall shipcall, List times)
- {
- ShipcallControlModel? selectedSCMModel = null;
+ #endregion
- foreach (ShipcallControlModel scm in this._controlModels)
+ #region basic operations
+
+ private void AddShipcall(ShipcallControlModel scm)
+ {
+ if (scm.Shipcall == null) return;
+ _allShipcallsDict[scm.Shipcall.Id] = scm;
+
+ Shipcall shipcall = scm.Shipcall;
+ if (this._shipLookupDict.ContainsKey(shipcall.ShipId))
+ scm.Ship = this._shipLookupDict[shipcall.ShipId];
+ if (this._berthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
+ scm.Berth = this._berthLookupDict[shipcall.ArrivalBerthId ?? 0].Name;
+ scm.AssignParticipants(this._participants);
+
+ this.Dispatcher.Invoke(() =>
{
- if (scm.Shipcall?.Id == shipcall.Id)
+ ShipcallControl sc = new()
{
- selectedSCMModel = scm;
- break;
+ Height = 120,
+ ShipcallControlModel = scm,
+ ParticipantDict = _participantLookupDict
+ };
+ sc.EditTimesRequested += Sc_EditTimesRequested;
+ sc.EditRequested += Sc_EditRequested;
+ sc.RefreshData();
+ this._allShipCallsControlDict[scm.Shipcall.Id] = sc;
+ });
+ }
+
+ private void UpdateShipcall(ShipcallControlModel scm)
+ {
+ if(scm.Shipcall == null) return;
+ Shipcall shipcall = scm.Shipcall;
+ if (this._shipLookupDict.ContainsKey(shipcall.ShipId))
+ scm.Ship = this._shipLookupDict[shipcall.ShipId];
+ if (this._berthLookupDict.ContainsKey(shipcall.ArrivalBerthId ?? 0))
+ scm.Berth = this._berthLookupDict[shipcall.ArrivalBerthId ?? 0].Name;
+ scm.AssignParticipants(this._participants);
+ }
+
+ private void RemoveShipcall(int shipcallId)
+ {
+ this.Dispatcher.Invoke(() =>
+ {
+ this.stackPanel.Children.Remove(this._allShipCallsControlDict[shipcallId]);
+ });
+
+ ShipcallControlModel removeModel = this._allShipcallsDict[shipcallId];
+ _visibleControlModels.Remove(removeModel);
+
+ this._allShipCallsControlDict.Remove(shipcallId);
+ this._allShipcallsDict.Remove(shipcallId);
+ }
+
+ private void FilterShipcalls()
+ {
+ SearchFilterModel sfm = this.searchFilterControl.SearchFilter;
+
+ this._visibleControlModels.Clear();
+ // first add everything
+ this._visibleControlModels.AddRange(_allShipcallsDict.Values);
+
+ // now remove elements whose filter criteria are met
+
+ if(sfm.Berths.Count > 0 )
+ {
+ this._visibleControlModels.RemoveAll(x => !sfm.Berths.Contains((x.Shipcall?.ArrivalBerthId) ?? -1));
+ }
+
+ if(sfm.Agencies.Count > 0 )
+ {
+ this._visibleControlModels.RemoveAll(x => !sfm.Agencies.Contains((x.GetParticipantIdForType(Extensions.ParticipantType.AGENCY)) ?? -1));
+ }
+
+ if(sfm.Categories.Count > 0 )
+ {
+ this._visibleControlModels.RemoveAll(x => !sfm.Categories.Contains((x.Shipcall?.Type) ?? -1));
+ }
+
+ if(!string.IsNullOrEmpty(sfm.SearchString))
+ {
+ this._visibleControlModels.RemoveAll(x => !x.ContainsRemarkText(sfm.SearchString));
+ }
+
+ if(sfm.ShipLengthTo != null)
+ {
+ this._visibleControlModels.RemoveAll(x => x.Ship?.Length > sfm.ShipLengthTo);
+ }
+
+ if(sfm.ShipLengthFrom != null)
+ {
+ this._visibleControlModels.RemoveAll(x => x.Ship?.Length < sfm.ShipLengthFrom);
+ }
+
+ if(sfm.EtaFrom != null)
+ {
+ this._visibleControlModels.RemoveAll(x => x.Shipcall?.Eta < sfm.EtaFrom);
+ }
+
+ if(sfm.EtaTo != null)
+ {
+ this._visibleControlModels.RemoveAll(x => x.Shipcall?.Eta > sfm.EtaTo);
+ }
+
+ if(!_showCanceled ?? true) // canceled calls are filtered by default
+ {
+ this._visibleControlModels.RemoveAll(x => x.Shipcall?.Canceled ?? true);
+ }
+
+ if (this._sortOrder != null)
+ {
+ switch(this._sortOrder)
+ {
+ case Extensions.SortOrder.SHIP_NAME:
+ this._visibleControlModels.Sort((x, y) => { if (x.Ship == null) return 0; if (y.Ship == null) return 0; return x.Ship.Name.CompareTo(y.Ship.Name); });
+ break;
+ case Extensions.SortOrder.MODIFIED:
+ this._visibleControlModels.Sort((x, y) => { if (x.Shipcall == null) return 0; if (y.Shipcall == null) return 0; return DateTime.Compare(x.Shipcall.Modified ?? x.Shipcall.Created, y.Shipcall.Modified ?? x.Shipcall.Created); });
+ break;
+ case Extensions.SortOrder.ETA_ETD:
+ this._visibleControlModels.Sort((x, y) =>
+ {
+ if (x.Shipcall == null) return 0;
+ if (y.Shipcall == null) return 0;
+ DateTime xDate = (x.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? x.Shipcall.Eta : x.Shipcall.Etd ?? x.Shipcall.Eta;
+ DateTime yDate = (y.Shipcall.Type == (int) Extensions.TypeEnum.Incoming) ? y.Shipcall.Eta : y.Shipcall.Etd ?? y.Shipcall.Eta;
+ return DateTime.Compare(xDate, yDate);
+ });
+ break;
+ default:
+ break;
}
}
+ }
- if (selectedSCMModel != null)
- {
- selectedSCMModel.Shipcall = shipcall;
- selectedSCMModel.Times = times;
- }
- else
- {
- // no: create new entry
- selectedSCMModel = new()
- {
- Shipcall = shipcall,
- Times = times
- };
- 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].Name;
+
- _controlModels.Add(selectedSCMModel);
- this.Dispatcher.Invoke(new Action(() =>
+ #endregion
+
+ private void UpdateUI()
+ {
+
+ this.Dispatcher.Invoke(new Action(() =>
+ {
+ this.stackPanel.Children.Clear();
+ foreach(ShipcallControlModel visibleModel in this._visibleControlModels)
{
- ShipcallControl sc = new()
+ if (visibleModel.Shipcall == null) continue; // should not happen
+ if(this._allShipCallsControlDict.ContainsKey(visibleModel.Shipcall.Id))
{
- Height = 120,
- ShipcallControlModel = selectedSCMModel,
- ParticipantDict = _participantLookupDict
- };
- sc.EditTimesRequested += Sc_EditTimesRequested;
- 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();
+ this._allShipCallsControlDict[visibleModel.Shipcall.Id].RefreshData();
+ this.stackPanel.Children.Add(this._allShipCallsControlDict[visibleModel.Shipcall.Id]);
+ }
+ }
}));
}
+ #region control event handler
+
private async void Sc_EditRequested(ShipcallControl obj)
{
if (obj.ShipcallControlModel != null)
@@ -391,6 +557,10 @@ namespace BreCalClient
}
}
+ #endregion
+
+ #region helper
+
private void ShowErrorDialog(string message, string caption)
{
Dispatcher.Invoke(new Action(() =>
@@ -399,6 +569,12 @@ namespace BreCalClient
}));
}
+ private void EnableControlsForParticipant()
+ {
+ if (App.Participant.IsTypeFlagSet(Extensions.ParticipantType.BSMD))
+ this.buttonNew.Visibility = Visibility.Visible;
+ }
+
#endregion
}
diff --git a/src/BreCalClient/Properties/Settings.Designer.cs b/src/BreCalClient/Properties/Settings.Designer.cs
index d11ff1d..ffe9b78 100644
--- a/src/BreCalClient/Properties/Settings.Designer.cs
+++ b/src/BreCalClient/Properties/Settings.Designer.cs
@@ -49,5 +49,14 @@ namespace BreCalClient.Properties {
return ((string)(this["APP_TITLE"]));
}
}
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://www.textbausteine.net/")]
+ public string LOGO_IMAGE_URL {
+ get {
+ return ((string)(this["LOGO_IMAGE_URL"]));
+ }
+ }
}
}
diff --git a/src/BreCalClient/Properties/Settings.settings b/src/BreCalClient/Properties/Settings.settings
index fd3a161..3560eda 100644
--- a/src/BreCalClient/Properties/Settings.settings
+++ b/src/BreCalClient/Properties/Settings.settings
@@ -11,5 +11,8 @@
!!Bremen calling Testversion!!
+
+ https://www.textbausteine.net/
+
\ No newline at end of file
diff --git a/src/BreCalClient/ReadMe.md b/src/BreCalClient/ReadMe.md
new file mode 100644
index 0000000..bcf3b10
--- /dev/null
+++ b/src/BreCalClient/ReadMe.md
@@ -0,0 +1,18 @@
+# Bremen calling WPF client
+
+## Introduction
+
+## API / code generation
+
+The Rest API client is generated from the OpenAPI specification [BreCalApi.yaml](../../misc/BreCalApiyaml) into the C# file [BreCalApi.cs](../../misc/BreCalApi.cs).
+In order to do so an extension for Visual Studio needs to be installed: REST API Client Code Generator for VS 2022.
+
+https://marketplace.visualstudio.com/items?itemName=ChristianResmaHelle.ApiClientCodeGenerator2022
+
+This extension has multiple generators, for this project OpenApiCodeGenerator is used (must be set on the yaml file in the project settings).
+Internally this uses Java, currently > 55 which translates into Java JDK 17 LTS.
+If code generation is not working please have a look in the output pane and select appropriate output source.
+
+## Installation
+
+The client is deployed via ClickOnce.
diff --git a/src/BreCalClient/Resources/Resources.Designer.cs b/src/BreCalClient/Resources/Resources.Designer.cs
index 79184b3..da52d12 100644
--- a/src/BreCalClient/Resources/Resources.Designer.cs
+++ b/src/BreCalClient/Resources/Resources.Designer.cs
@@ -316,6 +316,15 @@ namespace BreCalClient.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Clear filters.
+ ///
+ public static string textClearFilters {
+ get {
+ return ResourceManager.GetString("textClearFilters", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Clear value.
///
@@ -694,6 +703,15 @@ namespace BreCalClient.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Show cancelled calls.
+ ///
+ public static string textShowCancelledShipcalls {
+ get {
+ return ResourceManager.GetString("textShowCancelledShipcalls", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Sort order.
///
diff --git a/src/BreCalClient/Resources/Resources.de.resx b/src/BreCalClient/Resources/Resources.de.resx
index f4bff42..64c1608 100644
--- a/src/BreCalClient/Resources/Resources.de.resx
+++ b/src/BreCalClient/Resources/Resources.de.resx
@@ -370,4 +370,10 @@
Passwort geändert.
+
+ Filter löschen
+
+
+ Stornierte anzeigen
+
\ No newline at end of file
diff --git a/src/BreCalClient/Resources/Resources.resx b/src/BreCalClient/Resources/Resources.resx
index 34fbec4..b80541f 100644
--- a/src/BreCalClient/Resources/Resources.resx
+++ b/src/BreCalClient/Resources/Resources.resx
@@ -199,6 +199,9 @@
Clear assignment
+
+ Clear filters
+
Clear value
@@ -325,6 +328,9 @@
Ship length
+
+ Show cancelled calls
+
Sort order
diff --git a/src/BreCalClient/SearchFilterControl.xaml b/src/BreCalClient/SearchFilterControl.xaml
index bca84da..90c4e36 100644
--- a/src/BreCalClient/SearchFilterControl.xaml
+++ b/src/BreCalClient/SearchFilterControl.xaml
@@ -59,23 +59,23 @@
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
diff --git a/src/BreCalClient/SearchFilterControl.xaml.cs b/src/BreCalClient/SearchFilterControl.xaml.cs
index 5315e76..bee9ed4 100644
--- a/src/BreCalClient/SearchFilterControl.xaml.cs
+++ b/src/BreCalClient/SearchFilterControl.xaml.cs
@@ -16,23 +16,41 @@ namespace BreCalClient
public partial class SearchFilterControl : UserControl
{
+ #region private fields
+
+ private SearchFilterModel _model = new();
+
+ #endregion
+
#region Construction
public SearchFilterControl()
{
InitializeComponent();
+ this.DataContext = this._model;
}
#endregion
#region events
+ ///
+ /// historically we love a clickable logo and see what will happen
+ ///
public event Action? LogoImageClicked;
+ ///
+ /// if the user somewhat changes the filters trigger this
+ ///
+ internal event Action? SearchFilterChanged;
+
#endregion
#region Properties
+ public string FilterAsJson { get; set; } = "";
+
+ internal SearchFilterModel SearchFilter { get { return _model; } }
#endregion
@@ -48,6 +66,19 @@ namespace BreCalClient
this.comboBoxAgencies.ItemsSource = agencies;
}
+ public void ClearFilters()
+ {
+ this._model = new SearchFilterModel();
+ this.comboBoxAgencies.UnSelectAll();
+ this.comboBoxBerths.UnSelectAll();
+ this.comboBoxCategories.UnSelectAll();
+ this.datePickerETAFrom.SelectedDate = null;
+ this.datePickerETATo.SelectedDate = null;
+ this.textBoxSearch.Clear();
+ this.upDownShiplengthFrom.Value = null;
+ this.upDownShiplengthTo.Value = null;
+ }
+
#endregion
#region event handler
@@ -60,6 +91,69 @@ namespace BreCalClient
private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
this.comboBoxCategories.ItemsSource = Enum.GetValues(typeof(Extensions.TypeEnum));
+ }
+
+ private void datePickerETAFrom_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+ {
+ SearchFilterChanged?.Invoke();
+ }
+
+ private void datePickerETATo_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
+ {
+ //_model.EtaTo = datePickerETATo.SelectedDate;
+ SearchFilterChanged?.Invoke();
+ }
+
+ private void comboBoxCategories_ItemSelectionChanged(object sender, Xceed.Wpf.Toolkit.Primitives.ItemSelectionChangedEventArgs e)
+ {
+ _model.Categories.Clear();
+ foreach(int category in comboBoxCategories.SelectedItems)
+ _model.Categories.Add(category);
+
+ SearchFilterChanged?.Invoke();
+ }
+
+ private void upDownShiplengthFrom_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs