Compare commits
62 Commits
develop
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
| 80e35223e0 | |||
| dd61368233 | |||
| 5bf5a2c8fa | |||
| a289b014a3 | |||
| f26465398a | |||
| cc743cd602 | |||
| fe2499707d | |||
| ccef84e119 | |||
| 1f9a3876ad | |||
| 4007459e93 | |||
| c5a88cb8f2 | |||
| 5edfa0522f | |||
| 1164c8055d | |||
| dc62bd005a | |||
| 70d8f053bb | |||
| 4cacc4809c | |||
| 3734e672fc | |||
| db0bcea485 | |||
|
|
29618fbf93 | ||
| e28739561f | |||
|
|
a92338c92e | ||
| f690387be8 | |||
| 3579d779e8 | |||
| c705b4396f | |||
| 3e4eebfb7b | |||
| 032f0ebba8 | |||
| 7abbd190b5 | |||
| afac489299 | |||
| 8e5b20995d | |||
| f2328fb18c | |||
| 212e76f7cb | |||
| f58688499a | |||
| 9f80f2cf5f | |||
| f87901e432 | |||
| ec65355473 | |||
| f232285e76 | |||
| b0c6b639be | |||
| 634c638e27 | |||
| 829b7d9c3c | |||
| 56d9346f9d | |||
| 8b2b454f97 | |||
| 7147b92c75 | |||
| f0cc749026 | |||
| 1cf2f3b8de | |||
| 16e244e757 | |||
| 3455139c74 | |||
| 1a3146cf85 | |||
| 7432e58b6a | |||
| 16b8b6366b | |||
| d25eea2f92 | |||
| 004908e9c0 | |||
| dc39a62293 | |||
| 504e36d97b | |||
| 32a1d93840 | |||
| 7d196957d3 | |||
| 28767fb4c3 | |||
| 0a8e78e6d2 | |||
| 6a05e7494b | |||
| e7586b9747 | |||
| 7056f1f4d2 | |||
| 931b81d5e4 | |||
| 79ff161b4e |
@ -4833,7 +4833,7 @@ namespace BreCalClient.misc.Client
|
||||
{
|
||||
Proxy = null;
|
||||
UserAgent = WebUtility.UrlEncode("OpenAPI-Generator/1.0.0/csharp");
|
||||
BasePath = "https://brecaldevel.bsmd-emswe.eu";
|
||||
BasePath = "https://brecal.bsmd-emswe.eu";
|
||||
DefaultHeaders = new ConcurrentDictionary<string, string>();
|
||||
ApiKey = new ConcurrentDictionary<string, string>();
|
||||
ApiKeyPrefix = new ConcurrentDictionary<string, string>();
|
||||
@ -4841,7 +4841,7 @@ namespace BreCalClient.misc.Client
|
||||
{
|
||||
{
|
||||
new Dictionary<string, object> {
|
||||
{"url", "https://brecaldevel.bsmd-emswe.eu"},
|
||||
{"url", "https://brecal.bsmd-emswe.eu"},
|
||||
{"description", "Development server hosted on vcup"},
|
||||
}
|
||||
}
|
||||
@ -4860,7 +4860,7 @@ namespace BreCalClient.misc.Client
|
||||
IDictionary<string, string> defaultHeaders,
|
||||
IDictionary<string, string> apiKey,
|
||||
IDictionary<string, string> apiKeyPrefix,
|
||||
string basePath = "https://brecaldevel.bsmd-emswe.eu") : this()
|
||||
string basePath = "https://brecal.bsmd-emswe.eu") : this()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(basePath))
|
||||
throw new ArgumentException("The provided basePath is invalid.", "basePath");
|
||||
|
||||
@ -14,7 +14,7 @@ info:
|
||||
name: Use at your own risk
|
||||
url: 'https://www.bsmd.de/license'
|
||||
servers:
|
||||
- url: 'https://brecaldevel.bsmd-emswe.eu'
|
||||
- url: 'https://brecal.bsmd-emswe.eu'
|
||||
description: Development server hosted on vcup
|
||||
tags:
|
||||
- name: user
|
||||
|
||||
31
misc/delete_data.sql
Normal file
31
misc/delete_data.sql
Normal file
@ -0,0 +1,31 @@
|
||||
CREATE DEFINER=`ds`@`localhost` PROCEDURE `delete_data`()
|
||||
BEGIN
|
||||
DECLARE shipcall_id_var int;
|
||||
DECLARE done INT DEFAULT FALSE;
|
||||
|
||||
DECLARE shipcall_iter CURSOR FOR
|
||||
SELECT shipcall.id FROM shipcall
|
||||
LEFT JOIN times ON
|
||||
times.shipcall_id = shipcall.id AND times.participant_type = 8
|
||||
WHERE
|
||||
-- ARRIVAL
|
||||
(type = 1 AND GREATEST(shipcall.eta, COALESCE(times.eta_berth, 0)) <= CURRENT_DATE() - INTERVAL 1 MONTH) OR
|
||||
-- DEPARTURE / SHIFTING
|
||||
(type != 1 AND GREATEST(shipcall.etd, COALESCE(times.etd_berth, 0)) <= CURRENT_DATE() - INTERVAL 1 MONTH);
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||||
|
||||
OPEN shipcall_iter;
|
||||
|
||||
delete_loop: LOOP
|
||||
FETCH shipcall_iter INTO shipcall_id_var;
|
||||
IF done THEN
|
||||
LEAVE delete_loop;
|
||||
END IF;
|
||||
DELETE FROM shipcall_participant_map WHERE shipcall_id = shipcall_id_var;
|
||||
DELETE FROM shipcall_tug_map WHERE shipcall_id = shipcall_id_var;
|
||||
DELETE FROM times WHERE shipcall_id = shipcall_id_var;
|
||||
DELETE FROM shipcall WHERE id = shipcall_id_var;
|
||||
END LOOP;
|
||||
CLOSE shipcall_iter;
|
||||
END
|
||||
@ -2,7 +2,7 @@
|
||||
-- evaluation_time: Time when the "traffic light" was last changed
|
||||
-- evaluation_notifications_sent: Flag to indicate if notifications were sent for the current evaluation
|
||||
|
||||
ALTER TABLE `bremen_calling_devel`.`shipcall`
|
||||
ALTER TABLE `bremen_calling_test`.`shipcall`
|
||||
ADD COLUMN `evaluation_time` DATETIME NULL DEFAULT NULL AFTER `evaluation_message`,
|
||||
ADD COLUMN `evaluation_notifications_sent` BIT NULL AFTER `evaluation_time`,
|
||||
ADD COLUMN `time_ref_point` INT NULL DEFAULT 0 COMMENT 'Index of a location which is the reference point for all time value entries, e.g. berth or Geeste' AFTER `modified`;
|
||||
@ -12,10 +12,10 @@ ADD COLUMN `time_ref_point` INT NULL DEFAULT 0 COMMENT 'Index of a location whic
|
||||
-- removed reference to participant and times and dropped unnecessary columns
|
||||
-- added reference to shipcall
|
||||
|
||||
ALTER TABLE `bremen_calling_devel`.`notification`
|
||||
ALTER TABLE `bremen_calling_test`.`notification`
|
||||
DROP FOREIGN KEY `FK_NOT_TIMES`,
|
||||
DROP FOREIGN KEY `FK_NOT_PART`;
|
||||
ALTER TABLE `bremen_calling_devel`.`notification`
|
||||
ALTER TABLE `bremen_calling_test`.`notification`
|
||||
DROP COLUMN `deleted`,
|
||||
DROP COLUMN `acknowledged`,
|
||||
DROP COLUMN `participant_id`,
|
||||
@ -25,10 +25,10 @@ ADD INDEX `FK_NOTIFICATION_SHIPCALL_idx` (`shipcall_id` ASC) VISIBLE,
|
||||
DROP INDEX `FK_NOT_PART` ,
|
||||
DROP INDEX `FK_NOT_TIMES` ;
|
||||
;
|
||||
ALTER TABLE `bremen_calling_devel`.`notification`
|
||||
ALTER TABLE `bremen_calling_test`.`notification`
|
||||
ADD CONSTRAINT `FK_NOTIFICATION_SHIPCALL`
|
||||
FOREIGN KEY (`shipcall_id`)
|
||||
REFERENCES `bremen_calling_devel`.`shipcall` (`id`)
|
||||
REFERENCES `bremen_calling_test`.`shipcall` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
@ -36,22 +36,22 @@ ADD CONSTRAINT `FK_NOTIFICATION_SHIPCALL`
|
||||
-- added notification flags
|
||||
-- participant reference is now mandatory
|
||||
|
||||
ALTER TABLE `bremen_calling_devel`.`user`
|
||||
ALTER TABLE `bremen_calling_test`.`user`
|
||||
DROP FOREIGN KEY `FK_USER_PART`;
|
||||
ALTER TABLE `bremen_calling_devel`.`user`
|
||||
ALTER TABLE `bremen_calling_test`.`user`
|
||||
ADD COLUMN `notify_email` BIT NULL DEFAULT NULL AFTER `api_key`,
|
||||
ADD COLUMN `notify_whatsapp` BIT NULL DEFAULT NULL AFTER `notify_email`,
|
||||
ADD COLUMN `notify_signal` BIT NULL DEFAULT NULL AFTER `notify_whatsapp`,
|
||||
ADD COLUMN `notify_popup` BIT NULL DEFAULT NULL AFTER `notify_signal`,
|
||||
CHANGE COLUMN `participant_id` `participant_id` INT UNSIGNED NOT NULL ;
|
||||
ALTER TABLE `bremen_calling_devel`.`user`
|
||||
ALTER TABLE `bremen_calling_test`.`user`
|
||||
ADD CONSTRAINT `FK_USER_PART`
|
||||
FOREIGN KEY (`participant_id`)
|
||||
REFERENCES `bremen_calling_devel`.`participant` (`id`);
|
||||
REFERENCES `bremen_calling_test`.`participant` (`id`);
|
||||
|
||||
-- History table for change tracking
|
||||
|
||||
CREATE TABLE `bremen_calling_devel`.`history` (
|
||||
CREATE TABLE `bremen_calling_test`.`history` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`participant_id` INT UNSIGNED NOT NULL,
|
||||
`user_id` INT UNSIGNED NOT NULL,
|
||||
@ -65,31 +65,31 @@ COMMENT = 'This table stores a history of changes made to shipcalls so that ever
|
||||
|
||||
-- and foreign keys
|
||||
|
||||
ALTER TABLE `bremen_calling_devel`.`history`
|
||||
ALTER TABLE `bremen_calling_test`.`history`
|
||||
ADD INDEX `FK_HISTORY_PARTICIPANT_idx` (`participant_id` ASC) VISIBLE,
|
||||
ADD INDEX `FK_HISTORY_SHIPCALL_idx` (`shipcall_id` ASC) VISIBLE;
|
||||
;
|
||||
ALTER TABLE `bremen_calling_devel`.`history`
|
||||
ALTER TABLE `bremen_calling_test`.`history`
|
||||
ADD CONSTRAINT `FK_HISTORY_PARTICIPANT`
|
||||
FOREIGN KEY (`participant_id`)
|
||||
REFERENCES `bremen_calling_devel`.`participant` (`id`)
|
||||
REFERENCES `bremen_calling_test`.`participant` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION,
|
||||
ADD CONSTRAINT `FK_HISTORY_SHIPCALL`
|
||||
FOREIGN KEY (`shipcall_id`)
|
||||
REFERENCES `bremen_calling_devel`.`shipcall` (`id`)
|
||||
REFERENCES `bremen_calling_test`.`shipcall` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION,
|
||||
ADD CONSTRAINT `FK_HISTORY_USER`
|
||||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `bremen_calling_devel`.`user` (`id`)
|
||||
REFERENCES `bremen_calling_test`.`user` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION;
|
||||
|
||||
-- add additional fields to times
|
||||
|
||||
ALTER TABLE `bremen_calling_devel`.`times`
|
||||
ALTER TABLE `bremen_calling_test`.`times`
|
||||
ADD COLUMN `ata` DATETIME NULL DEFAULT NULL COMMENT 'Relevant only for mooring, this field can be used to record actual ATA' AFTER `participant_type`,
|
||||
ADD COLUMN `atd` DATETIME NULL DEFAULT NULL COMMENT 'Relevant only for mooring, this field can be used to record actual ATD' AFTER `ata`,
|
||||
ADD COLUMN `eta_interval_end` DATETIME NULL DEFAULT NULL COMMENT 'If this value is set the times are given as interval instead of a single point in time. The start time value depends on the participant type.' AFTER `atd`;
|
||||
ADD COLUMN `eta_interval_end` DATETIME NULL DEFAULT NULL COMMENT 'If this value is set the times are given as interval instead of a single point in time. The start time value depends on the participant type.' AFTER `atd`,
|
||||
ADD COLUMN `etd_interval_end` DATETIME NULL DEFAULT NULL COMMENT 'If this value is set the times are given as interval instead of a single point in time. The start time value depends on the participant type.' AFTER `eta_interval_end`;
|
||||
@ -1 +1 @@
|
||||
1.2.0.0
|
||||
1.2.1.2
|
||||
@ -25,7 +25,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
@ -11,16 +11,16 @@
|
||||
<applicationSettings>
|
||||
<BreCalClient.Properties.Settings>
|
||||
<setting name="BG_COLOR" serializeAs="String">
|
||||
<value>#1D751F</value>
|
||||
<value>#203864</value>
|
||||
</setting>
|
||||
<setting name="APP_TITLE" serializeAs="String">
|
||||
<value>!!Bremen calling Testversion!!</value>
|
||||
<value>Bremen calling</value>
|
||||
</setting>
|
||||
<setting name="LOGO_IMAGE_URL" serializeAs="String">
|
||||
<value>https://www.textbausteine.net/</value>
|
||||
</setting>
|
||||
<setting name="API_URL" serializeAs="String">
|
||||
<value>https://brecaldevel.bsmd-emswe.eu</value>
|
||||
<value>https://brecal.bsmd-emswe.eu</value>
|
||||
</setting>
|
||||
</BreCalClient.Properties.Settings>
|
||||
</applicationSettings>
|
||||
|
||||
@ -2,16 +2,19 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:BreCalClient"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
StartupUri="MainWindow.xaml" Exit="Application_Exit" Startup="Application_Startup" >
|
||||
<Application.Resources>
|
||||
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
|
||||
|
||||
<ResourceDictionary Source="Resources\StringResources.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarWidthKey}">10</sys:Double>
|
||||
<sys:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarHeightKey}">10</sys:Double>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<StartupObject>BreCalClient.App</StartupObject>
|
||||
<AssemblyOriginatorKeyFile>..\..\misc\brecal.snk</AssemblyOriginatorKeyFile>
|
||||
<AssemblyVersion>1.2.0.0</AssemblyVersion>
|
||||
<FileVersion>1.2.0.0</FileVersion>
|
||||
<AssemblyVersion>1.2.1.2</AssemblyVersion>
|
||||
<FileVersion>1.2.1.2</FileVersion>
|
||||
<Title>Bremen calling client</Title>
|
||||
<Description>A Windows WPF client for the Bremen calling API.</Description>
|
||||
<ApplicationIcon>containership.ico</ApplicationIcon>
|
||||
<AssemblyName>BreCalDevelClient</AssemblyName>
|
||||
<AssemblyName>BreCalClient</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -37,6 +37,7 @@
|
||||
<None Remove="Resources\lock.png" />
|
||||
<None Remove="Resources\lock_open.png" />
|
||||
<None Remove="Resources\logo_bremen_calling.png" />
|
||||
<None Remove="Resources\nav_refresh_green.png" />
|
||||
<None Remove="Resources\ship2.png" />
|
||||
<None Remove="Resources\sign_warning.png" />
|
||||
<None Remove="Resources\trafficlight_green.png" />
|
||||
@ -92,6 +93,7 @@
|
||||
<Resource Include="Resources\lock.png" />
|
||||
<Resource Include="Resources\lock_open.png" />
|
||||
<Resource Include="Resources\logo_bremen_calling.png" />
|
||||
<Resource Include="Resources\nav_refresh_green.png" />
|
||||
<Resource Include="Resources\ship2.png" />
|
||||
<Resource Include="Resources\sign_warning.png" />
|
||||
<Resource Include="Resources\StringResources.de.xaml">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2023 schick Informatik
|
||||
// Description: Static lists used everywhere
|
||||
//
|
||||
//
|
||||
|
||||
using BreCalClient.misc.Model;
|
||||
using System.Collections.Concurrent;
|
||||
@ -30,9 +30,13 @@ namespace BreCalClient
|
||||
private readonly static ConcurrentDictionary<int, Berth> _berthLookupDict = new();
|
||||
private readonly static Dictionary<int, Participant> _participantLookupDict = new();
|
||||
|
||||
/// <summary>
|
||||
/// List of TimeRef points
|
||||
/// </summary>
|
||||
// TODO: To make this portable the list of texts should come from a configuration file
|
||||
private readonly static List<string> _timeRefs = new List<string>
|
||||
{
|
||||
"Liegeplatz",
|
||||
"ETB",
|
||||
"Geeste",
|
||||
"TN-Weser"
|
||||
};
|
||||
@ -113,7 +117,7 @@ namespace BreCalClient
|
||||
aList.Clear();
|
||||
mList.Clear();
|
||||
pList.Clear();
|
||||
tList.Clear();
|
||||
tList.Clear();
|
||||
terList.Clear();
|
||||
|
||||
foreach (Participant p in participants)
|
||||
@ -147,7 +151,7 @@ namespace BreCalClient
|
||||
if (!ship.Deleted)
|
||||
_ships.Add(sm);
|
||||
_allShips.Add(sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -141,8 +141,7 @@ namespace BreCalClient
|
||||
#region protected
|
||||
|
||||
protected void addItem(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-us");
|
||||
{
|
||||
if (!this.IsReadOnly)
|
||||
{
|
||||
this.CreateRequested?.Invoke();
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="Name" HorizontalAlignment="Right" />
|
||||
<TextBox x:Name="textBoxName" Grid.Column="1" Margin="2" VerticalContentAlignment="Center" Text="{Binding Name, Mode=OneWay}" />
|
||||
<TextBox x:Name="textBoxName" Grid.Column="1" Margin="2" VerticalContentAlignment="Center" Text="{Binding Name, Mode=OneWay}" TextChanged="textBoxName_TextChanged" MaxLength="64"/>
|
||||
<Label Content="{x:Static p:Resources.textTugCompany}" HorizontalAlignment="Right" Grid.Row="1" />
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -38,9 +38,9 @@
|
||||
</Button>
|
||||
</Grid>
|
||||
<Label Content="IMO" HorizontalAlignment="Right" Grid.Row="2" />
|
||||
<xctk:IntegerUpDown Name="integerUpDownIMO" Grid.Column="1" Grid.Row="2" Value="{Binding Imo, Mode=OneWay}" Margin="2" Minimum="1000000" Maximum="9999999" ShowButtonSpinner="False"/>
|
||||
<xctk:IntegerUpDown Name="integerUpDownIMO" Grid.Column="1" Grid.Row="2" Value="{Binding Imo, Mode=OneWay}" Margin="2" Minimum="1000000" Maximum="9999999" ShowButtonSpinner="False" ValueChanged="integerUpDownIMO_ValueChanged"/>
|
||||
<Label Content="{x:Static p:Resources.textCallsign}" HorizontalAlignment="Right" Grid.Row="3" />
|
||||
<TextBox x:Name="textBoxCallsign" Grid.Column="1" Grid.Row="3" Margin="2" VerticalContentAlignment="Center" Text="{Binding Callsign, Mode=OneWay}" />
|
||||
<TextBox x:Name="textBoxCallsign" Grid.Column="1" Grid.Row="3" Margin="2" VerticalContentAlignment="Center" Text="{Binding Callsign, Mode=OneWay}" MaxLength="8"/>
|
||||
<Label Content="{x:Static p:Resources.textLength}" HorizontalAlignment="Right" Grid.Row="4" />
|
||||
<xctk:DoubleUpDown Name="doubleUpDownLength" Grid.Row="4" Grid.Column="1" Value="{Binding Length, Mode=OneWay}" Margin="2" Minimum="0" />
|
||||
<Label Content="{x:Static p:Resources.textWidth}" HorizontalAlignment="Right" Grid.Row="5" />
|
||||
|
||||
@ -28,7 +28,7 @@ namespace BreCalClient
|
||||
private void buttonOK_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
this.Ship.Name = this.textBoxName.Text.Trim();
|
||||
this.Ship.Name = this.textBoxName.Text.ToUpper().Trim();
|
||||
|
||||
if (this.comboBoxParticipants.SelectedItem != null)
|
||||
{
|
||||
@ -40,7 +40,7 @@ namespace BreCalClient
|
||||
this.Ship.IsTug = false;
|
||||
}
|
||||
this.Ship.Imo = this.integerUpDownIMO.Value;
|
||||
this.Ship.Callsign = this.textBoxCallsign.Text.Trim();
|
||||
this.Ship.Callsign = this.textBoxCallsign.Text.ToUpper().Trim();
|
||||
this.Ship.Length = (float?) this.doubleUpDownLength.Value;
|
||||
this.Ship.Width = (float?) this.doubleUpDownWidth.Value;
|
||||
this.DialogResult = true;
|
||||
@ -61,11 +61,27 @@ namespace BreCalClient
|
||||
this.comboBoxParticipants.SelectedItem = p;
|
||||
}
|
||||
}
|
||||
this.EnableOK();
|
||||
}
|
||||
|
||||
private void buttonResetParticipant_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.comboBoxParticipants.SelectedItem = null;
|
||||
}
|
||||
|
||||
private void textBoxName_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
this.EnableOK();
|
||||
}
|
||||
|
||||
private void integerUpDownIMO_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
this.EnableOK();
|
||||
}
|
||||
|
||||
private void EnableOK()
|
||||
{
|
||||
this.buttonOK.IsEnabled = (this.textBoxName.Text.Length > 2) && (this.integerUpDownIMO.Value.HasValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,13 +4,14 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:BreCalClient"
|
||||
xmlns:p = "clr-namespace:BreCalClient.Resources"
|
||||
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
|
||||
xmlns:p = "clr-namespace:BreCalClient.Resources"
|
||||
xmlns:api="clr-namespace:BreCalClient.misc.Model"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W1Left}" Top="{local:SettingBinding W1Top}"
|
||||
Title="{x:Static p:Resources.textEditShipcall}" Height="270" Width="800" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
|
||||
<Window.Resources>
|
||||
<local:BoolToIndexConverter x:Key="boolToIndexConverter" />
|
||||
<local:EnumToStringConverter x:Key="enumToStringConverter" />
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -45,8 +46,8 @@
|
||||
<Button x:Name="buttonEditShips" Grid.Column="1" Grid.Row="6" Margin="2" Content="{x:Static p:Resources.textEditShips}" Click="buttonEditShips_Click" Visibility="Hidden" />
|
||||
|
||||
<Label Content="{x:Static p:Resources.textType}" Grid.Column="2" Grid.Row="0" HorizontalContentAlignment="Right" />
|
||||
|
||||
<ComboBox x:Name="comboBoxCategories" Grid.Column="3" Margin="2" Grid.Row="0" SelectionChanged="comboBoxCategories_SelectionChanged"/>
|
||||
|
||||
<ComboBox ItemsSource="{local:Enumerate {x:Type api:ShipcallType}}" Grid.Column="3" Margin="2" Grid.Row="0" SelectionChanged="comboBoxCategories_SelectionChanged" x:Name="comboBoxCategories" />
|
||||
|
||||
<Label Content="{x:Static p:Resources.textBerth}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
|
||||
<Grid Grid.Row="1" Grid.Column="3">
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
using BreCalClient.misc.Api;
|
||||
using BreCalClient.misc.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using static BreCalClient.Extensions;
|
||||
@ -48,8 +49,16 @@ namespace BreCalClient
|
||||
{
|
||||
this.comboBoxAgency.ItemsSource = BreCalLists.Participants_Agent;
|
||||
|
||||
this.comboBoxShip.ItemsSource = BreCalLists.AllShips;
|
||||
this.comboBoxCategories.ItemsSource = Enum.GetValues(typeof(ShipcallType));
|
||||
this.comboBoxShip.ItemsSource = BreCalLists.Ships;
|
||||
Array types = Enum.GetValues(typeof(ShipcallType));
|
||||
List<ShipcallType> shipcallTypes = new();
|
||||
bool first = true;
|
||||
foreach(ShipcallType shipcallType in types)
|
||||
{
|
||||
if (!first) shipcallTypes.Add(shipcallType);
|
||||
else first = false;
|
||||
}
|
||||
|
||||
this.comboBoxArrivalBerth.ItemsSource = BreCalLists.Berths;
|
||||
this.comboBoxDepartureBerth.ItemsSource = BreCalLists.Berths;
|
||||
|
||||
@ -102,7 +111,7 @@ namespace BreCalClient
|
||||
|
||||
private void comboBoxCategories_SelectionChanged(object? sender, SelectionChangedEventArgs? e)
|
||||
{
|
||||
ShipcallType? type = this.comboBoxCategories.SelectedItem as ShipcallType?;
|
||||
ShipcallType? type = GetShipcallTypeFromCombobox();
|
||||
if (type != null)
|
||||
{
|
||||
switch (type)
|
||||
@ -114,6 +123,7 @@ namespace BreCalClient
|
||||
this.comboBoxDepartureBerth.SelectedIndex = -1;
|
||||
this.comboBoxDepartureBerth.IsEnabled = false;
|
||||
this.comboBoxArrivalBerth.IsEnabled = true;
|
||||
this.comboBoxTimeRef.IsEnabled = true;
|
||||
break;
|
||||
case ShipcallType.Departure:
|
||||
this.datePickerETA.IsEnabled = false;
|
||||
@ -122,12 +132,16 @@ namespace BreCalClient
|
||||
this.comboBoxArrivalBerth.SelectedIndex = -1;
|
||||
this.comboBoxArrivalBerth.IsEnabled = false;
|
||||
this.comboBoxDepartureBerth.IsEnabled = true;
|
||||
this.comboBoxTimeRef.IsEnabled = false;
|
||||
this.comboBoxTimeRef.SelectedIndex = 0;
|
||||
break;
|
||||
case ShipcallType.Shifting:
|
||||
this.datePickerETA.IsEnabled = true;
|
||||
this.datePickerETD.IsEnabled = true;
|
||||
this.comboBoxArrivalBerth.IsEnabled = true;
|
||||
this.comboBoxDepartureBerth.IsEnabled = true;
|
||||
this.comboBoxTimeRef.IsEnabled = false;
|
||||
this.comboBoxTimeRef.SelectedIndex = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -148,6 +162,12 @@ namespace BreCalClient
|
||||
|
||||
#region private methods
|
||||
|
||||
ShipcallType? GetShipcallTypeFromCombobox()
|
||||
{
|
||||
EnumToStringConverter enumToStringConverter = new();
|
||||
return (ShipcallType?)enumToStringConverter.ConvertBack(this.comboBoxCategories.SelectedItem, typeof(ShipcallType), new object(), System.Globalization.CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
void CheckForCompletion()
|
||||
{
|
||||
bool isEnabled = true;
|
||||
@ -161,7 +181,7 @@ namespace BreCalClient
|
||||
}
|
||||
else
|
||||
{
|
||||
ShipcallType callType = (ShipcallType)comboBoxCategories.SelectedItem;
|
||||
ShipcallType callType = GetShipcallTypeFromCombobox() ?? ShipcallType.Undefined;
|
||||
switch (callType)
|
||||
{
|
||||
case ShipcallType.Departure:
|
||||
@ -189,7 +209,7 @@ namespace BreCalClient
|
||||
{
|
||||
if (this.ShipcallModel.Shipcall != null)
|
||||
{
|
||||
this.ShipcallModel.Shipcall.Type = (ShipcallType) this.comboBoxCategories.SelectedItem;
|
||||
this.ShipcallModel.Shipcall.Type = GetShipcallTypeFromCombobox() ?? ShipcallType.Undefined;
|
||||
this.ShipcallModel.Shipcall.Eta = this.datePickerETA.Value;
|
||||
this.ShipcallModel.Shipcall.Etd = this.datePickerETD.Value;
|
||||
|
||||
@ -270,12 +290,18 @@ namespace BreCalClient
|
||||
if (this.ShipcallModel.Shipcall != null)
|
||||
{
|
||||
this.comboBoxTimeRef.SelectedIndex = this.ShipcallModel.Shipcall.TimeRefPoint ?? 0;
|
||||
this.comboBoxCategories.SelectedItem = this.ShipcallModel.Shipcall.Type;
|
||||
this.comboBoxCategories.SelectedItem = new EnumToStringConverter().Convert(this.ShipcallModel.Shipcall.Type, typeof(ShipcallType), new object(), System.Globalization.CultureInfo.CurrentCulture);
|
||||
if (this.ShipcallModel.Shipcall.Eta != DateTime.MinValue)
|
||||
this.datePickerETA.Value = this.ShipcallModel.Shipcall.Eta;
|
||||
// this.textBoxVoyage.Text = this.ShipcallModel.Shipcall.Voyage;
|
||||
this.datePickerETD.Value = this.ShipcallModel.Shipcall.Etd;
|
||||
this.comboBoxShip.SelectedValue = this.ShipcallModel.Shipcall.ShipId;
|
||||
if (BreCalLists.Ships.Find(x => x.Ship.Id == this.ShipcallModel.Shipcall.ShipId) != null)
|
||||
{
|
||||
this.comboBoxShip.SelectedValue = this.ShipcallModel.Shipcall.ShipId;
|
||||
} else
|
||||
{
|
||||
this.comboBoxShip.IsEnabled = false;
|
||||
}
|
||||
this.checkBoxCancelled.IsChecked = this.ShipcallModel.Shipcall.Canceled ?? false;
|
||||
|
||||
if (this.ShipcallModel.Shipcall.Type != ShipcallType.Shifting) // incoming, outgoing
|
||||
@ -370,7 +396,7 @@ namespace BreCalClient
|
||||
|
||||
// reload combobox
|
||||
this.comboBoxShip.ItemsSource = null;
|
||||
this.comboBoxShip.ItemsSource = BreCalLists.AllShips;
|
||||
this.comboBoxShip.ItemsSource = BreCalLists.Ships;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -8,13 +8,13 @@
|
||||
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W1Left}" Top="{local:SettingBinding W1Top}"
|
||||
Title="{x:Static p:Resources.textEditShipcall}" Height="403" Width="900" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
|
||||
Title="{x:Static p:Resources.textEditShipcall}" Height="403" Width="900" Loaded="Window_Loaded" ResizeMode="CanResizeWithGrip" Icon="Resources/containership.ico">
|
||||
<Window.Resources>
|
||||
<local:BoolToIndexConverter x:Key="boolToIndexConverter" />
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="0.15*"/>
|
||||
<ColumnDefinition Width="0.18*"/>
|
||||
<ColumnDefinition Width=".4*" />
|
||||
<ColumnDefinition Width="0.15*"/>
|
||||
<ColumnDefinition Width=".3*" />
|
||||
@ -31,7 +31,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Grid.Column="0">
|
||||
@ -67,7 +67,7 @@
|
||||
</ComboBox.ContextMenu>
|
||||
</ComboBox>
|
||||
<Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right" />
|
||||
<TextBox x:Name="textBoxBerthRemarks" Grid.Column="1" Grid.Row="4" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512"/>
|
||||
<TextBox x:Name="textBoxBerthRemarks" Grid.Column="1" Grid.Row="4" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512" TextWrapping="Wrap" SpellCheck.IsEnabled="True" AcceptsTab="False" ScrollViewer.VerticalScrollBarVisibility="Auto" />
|
||||
<Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right" FontWeight="Bold" />
|
||||
<xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="6" Margin="2" FormatString="N2" Minimum="0" Maximum="50" MaxLength="5" ValueChanged="doubleUpDownDraft_ValueChanged"/>
|
||||
<Label Content="{x:Static p:Resources.textTidalWindow}" FontWeight="DemiBold" Grid.Column="0" Grid.Row="7" HorizontalContentAlignment="Right"/>
|
||||
@ -127,7 +127,7 @@
|
||||
<CheckBox x:Name="checkBoxReplenishingTerminal" Grid.Column="2" Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
|
||||
<CheckBox x:Name="checkBoxReplenishingLock" Grid.Column="2" Grid.Row="9" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,4,0" />
|
||||
<Label Content="{x:Static p:Resources.textRemarks}" Grid.Row="10" Grid.Column="2" HorizontalAlignment="Right"/>
|
||||
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="10" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512"/>
|
||||
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="10" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512" TextWrapping="Wrap" SpellCheck.IsEnabled="True" AcceptsTab="False" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
|
||||
<StackPanel Grid.Row="14" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" IsEnabled="False" />
|
||||
|
||||
@ -255,7 +255,7 @@ namespace BreCalClient
|
||||
this.datePickerETA_End.IsEnabled = _editing;
|
||||
this.comboBoxArrivalBerth.IsEnabled = _editing;
|
||||
this.comboBoxPierside.IsEnabled = _editing;
|
||||
this.textBoxBerthRemarks.IsEnabled = _editing;
|
||||
this.textBoxBerthRemarks.IsReadOnly = !_editing;
|
||||
this.doubleUpDownDraft.IsEnabled = _editing;
|
||||
this.datePickerTidalWindowFrom.IsEnabled = _editing;
|
||||
this.datePickerTidalWindowTo.IsEnabled = _editing;
|
||||
@ -273,7 +273,7 @@ namespace BreCalClient
|
||||
this.checkBoxBunkering.IsEnabled = _editing;
|
||||
this.checkBoxReplenishingTerminal.IsEnabled = _editing;
|
||||
this.checkBoxReplenishingLock.IsEnabled = _editing;
|
||||
this.textBoxRemarks.IsEnabled = _editing;
|
||||
this.textBoxRemarks.IsReadOnly = !_editing;
|
||||
|
||||
CheckOKButton();
|
||||
}
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W1Left}" Top="{local:SettingBinding W1Top}"
|
||||
Title="{x:Static p:Resources.textEditShipcall}" Height="375" Width="900" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
|
||||
Title="{x:Static p:Resources.textEditShipcall}" Height="375" Width="900" Loaded="Window_Loaded" ResizeMode="CanResizeWithGrip" Icon="Resources/containership.ico">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="0.15*"/>
|
||||
<ColumnDefinition Width="0.18*"/>
|
||||
<ColumnDefinition Width=".4*" />
|
||||
<ColumnDefinition Width="0.15*"/>
|
||||
<ColumnDefinition Width=".3*" />
|
||||
@ -28,6 +28,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Grid.Column="0">
|
||||
@ -61,7 +62,7 @@
|
||||
</ComboBox.ContextMenu>
|
||||
</ComboBox>
|
||||
<Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="4" HorizontalContentAlignment="Right" />
|
||||
<TextBox x:Name="textBoxBerthRemarks" Grid.Column="1" Grid.Row="4" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512"/>
|
||||
<TextBox x:Name="textBoxBerthRemarks" Grid.Column="1" Grid.Row="4" Margin="2" Grid.RowSpan="2" VerticalContentAlignment="Top" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" MaxLength="512" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
<Label Content="{x:Static p:Resources.textDraft}" Grid.Column="0" Grid.Row="6" HorizontalContentAlignment="Right" FontWeight="Bold"/>
|
||||
<xctk:DoubleUpDown x:Name="doubleUpDownDraft" Grid.Column="1" Grid.Row="6" Margin="2" FormatString="N2" Minimum="0" Maximum="50" MaxLength="5" ValueChanged="doubleUpDownDraft_ValueChanged"/>
|
||||
<Label Content="{x:Static p:Resources.textTidalWindow}" FontWeight="DemiBold" Grid.Column="0" Grid.Row="7" HorizontalContentAlignment="Right"/>
|
||||
@ -69,7 +70,7 @@
|
||||
<Label Content="{x:Static p:Resources.textTo}" Grid.Column="0" Grid.Row="9" HorizontalContentAlignment="Right"/>
|
||||
<xctk:DateTimePicker Name="datePickerTidalWindowFrom" Grid.Column="1" Grid.Row="8" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
|
||||
<xctk:DateTimePicker Name="datePickerTidalWindowTo" Grid.Column="1" Grid.Row="9" Margin="2" Format="Custom" FormatString="dd.MM. yyyy HH:mm"/>
|
||||
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="10" HorizontalContentAlignment="Right" />
|
||||
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="10" HorizontalContentAlignment="Right" VerticalAlignment="Center" />
|
||||
<CheckBox x:Name="checkBoxCanceled" Grid.Column="1" Grid.Row="10" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
|
||||
|
||||
<Label Content="{x:Static p:Resources.textTugRequired}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Right"/>
|
||||
@ -115,9 +116,9 @@
|
||||
<Label Content="{x:Static p:Resources.textRainSensitiveCargo}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="7" HorizontalAlignment="Right" />
|
||||
<CheckBox x:Name="checkBoxRainsensitiveCargo" Grid.Column="3" Grid.Row="7" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
|
||||
<Label Content="{x:Static p:Resources.textRemarks}" Grid.Column="2" Grid.Row="8" HorizontalContentAlignment="Right" />
|
||||
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="8" Margin="2" Grid.RowSpan="3" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512"/>
|
||||
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="8" Margin="2" Grid.RowSpan="4" VerticalContentAlignment="Top" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" MaxLength="512" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
|
||||
<StackPanel Grid.Row="11" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<StackPanel Grid.Row="12" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" IsEnabled="False" />
|
||||
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
|
||||
</StackPanel>
|
||||
|
||||
@ -247,7 +247,7 @@ namespace BreCalClient
|
||||
this.datePickerETD_End.IsEnabled = _editing;
|
||||
this.comboBoxDepartureBerth.IsEnabled = _editing;
|
||||
this.comboBoxPierside.IsEnabled = _editing;
|
||||
this.textBoxBerthRemarks.IsEnabled = _editing;
|
||||
this.textBoxBerthRemarks.IsReadOnly = !_editing;
|
||||
this.doubleUpDownDraft.IsEnabled = _editing;
|
||||
this.datePickerTidalWindowFrom.IsEnabled = _editing;
|
||||
this.datePickerTidalWindowTo.IsEnabled = _editing;
|
||||
@ -261,7 +261,7 @@ namespace BreCalClient
|
||||
this.checkBoxMooredLock.IsEnabled = _editing;
|
||||
this.comboBoxTerminal.IsEnabled = _editing;
|
||||
this.checkBoxRainsensitiveCargo.IsEnabled = _editing;
|
||||
this.textBoxRemarks.IsEnabled = _editing;
|
||||
this.textBoxRemarks.IsReadOnly = !_editing;
|
||||
|
||||
CheckOKButton();
|
||||
}
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W1Left}" Top="{local:SettingBinding W1Top}"
|
||||
Title="{x:Static p:Resources.textEditShipcall}" Height="490" Width="900" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
|
||||
Title="{x:Static p:Resources.textEditShipcall}" Height="490" Width="900" Loaded="Window_Loaded" ResizeMode="CanResizeWithGrip" Icon="Resources/containership.ico">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="0.15*"/>
|
||||
<ColumnDefinition Width="0.18*"/>
|
||||
<ColumnDefinition Width=".4*" />
|
||||
<ColumnDefinition Width="0.15*"/>
|
||||
<ColumnDefinition Width=".3*" />
|
||||
@ -30,7 +30,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
|
||||
@ -106,7 +106,7 @@
|
||||
</ComboBox.ContextMenu>
|
||||
</ComboBox>
|
||||
<Label Content="{x:Static p:Resources.textBerthRemarks}" Grid.Column="0" Grid.Row="12" HorizontalContentAlignment="Right" />
|
||||
<TextBox x:Name="textBoxBerthRemarksArrival" Grid.Column="1" Grid.Row="12" Margin="2,1,2,3" Grid.RowSpan="2" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512"/>
|
||||
<TextBox x:Name="textBoxBerthRemarksArrival" Grid.Column="1" Grid.Row="12" Margin="2,1,2,3" Grid.RowSpan="2" VerticalContentAlignment="Top" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" MaxLength="512" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
<Label Content="{x:Static p:Resources.textCancelled}" Grid.Column="0" Grid.Row="14" HorizontalContentAlignment="Right" />
|
||||
<CheckBox x:Name="checkBoxCanceled" Grid.Column="1" Grid.Row="14" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
|
||||
|
||||
@ -147,7 +147,7 @@
|
||||
<Label Content="{x:Static p:Resources.textRainSensitiveCargo}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="6" HorizontalAlignment="Right" />
|
||||
<CheckBox x:Name="checkBoxRainsensitiveCargo" Grid.Column="3" Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,4,0" />
|
||||
<Label Content="{x:Static p:Resources.textRemarks}" Grid.Column="2" Grid.Row="7" HorizontalContentAlignment="Right" />
|
||||
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="7" Margin="2,1,2,3" Grid.RowSpan="7" VerticalContentAlignment="Top" AcceptsReturn="True" MaxLength="512"/>
|
||||
<TextBox x:Name="textBoxRemarks" Grid.Column="3" Grid.Row="7" Margin="2,1,2,3" Grid.RowSpan="7" VerticalContentAlignment="Top" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" MaxLength="512" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
|
||||
<StackPanel Grid.Row="15" Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" IsEnabled="False"/>
|
||||
|
||||
@ -270,7 +270,7 @@ namespace BreCalClient
|
||||
this.datePickerETA.IsEnabled = _editing;
|
||||
this.comboBoxDepartureBerth.IsEnabled = _editing;
|
||||
this.comboBoxPiersideArrival.IsEnabled = _editing;
|
||||
this.textBoxBerthRemarksArrival.IsEnabled = _editing;
|
||||
this.textBoxBerthRemarksArrival.IsReadOnly = !_editing;
|
||||
this.checkBoxCanceled.IsEnabled = _editing;
|
||||
|
||||
|
||||
@ -281,7 +281,7 @@ namespace BreCalClient
|
||||
this.checkBoxMooredLock.IsEnabled = _editing;
|
||||
this.comboBoxTerminal.IsEnabled = _editing;
|
||||
this.checkBoxRainsensitiveCargo.IsEnabled = _editing;
|
||||
this.textBoxRemarks.IsEnabled = _editing;
|
||||
this.textBoxRemarks.IsReadOnly = !_editing;
|
||||
|
||||
CheckOKButton();
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W1Left}" Top="{local:SettingBinding W1Top}"
|
||||
Title="{x:Static p:Resources.textEditTimes}" Height="331" Width="500" Loaded="Window_Loaded" ResizeMode="NoResize" Icon="Resources/containership.ico">
|
||||
Title="{x:Static p:Resources.textEditTimes}" Height="331" Width="500" Loaded="Window_Loaded" ResizeMode="CanResizeWithGrip" Icon="Resources/containership.ico">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width=".20*" />
|
||||
@ -23,7 +23,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="56" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
<Button x:Name="buttonFixedOrder" Grid.Row="0" Grid.Column="1" Margin="2" Click="buttonFixedOrder_Click" Width="28" HorizontalAlignment="Left">
|
||||
@ -45,7 +45,7 @@
|
||||
<ColumnDefinition Width=".5*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<xctk:DateTimePicker IsEnabled="False" Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerETABerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
||||
<xctk:DateTimePicker IsEnabled="False" Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerETABerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm" ValueChanged="datePickerETABerth_ValueChanged">
|
||||
<xctk:DateTimePicker.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearETA" Click="contextMenuItemClearETA_Click" >
|
||||
@ -77,7 +77,7 @@
|
||||
<ColumnDefinition Width=".5*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<xctk:DateTimePicker IsEnabled="False" Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerETDBerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm">
|
||||
<xctk:DateTimePicker IsEnabled="False" Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerETDBerth" Format="Custom" FormatString="dd.MM. yyyy HH:mm" ValueChanged="datePickerETDBerth_ValueChanged">
|
||||
<xctk:DateTimePicker.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearETD" Click="contextMenuItemClearETD_Click" >
|
||||
@ -152,7 +152,7 @@
|
||||
</xctk:DateTimePicker>
|
||||
<!--CheckBox IsEnabled="False" Grid.Row="4" Grid.Column="2" Margin="4,0,0,0" Name="checkBoxZoneEntryFixed" VerticalAlignment="Center" /-->
|
||||
|
||||
<TextBox Grid.Row="7" Grid.Column="1" Margin="2" Name="textBoxRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" IsEnabled="False" MaxLength="512"/>
|
||||
<TextBox Grid.Row="7" Grid.Column="1" Margin="2" Name="textBoxRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" IsReadOnly="True" MaxLength="512" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
<StackPanel Grid.Row="8" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" IsEnabled="False" />
|
||||
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
|
||||
|
||||
@ -62,6 +62,16 @@ namespace BreCalClient
|
||||
SetLockButton(newValue);
|
||||
}
|
||||
|
||||
private void datePickerETABerth_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
CheckOKButton();
|
||||
}
|
||||
|
||||
private void datePickerETDBerth_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
CheckOKButton();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
@ -114,6 +124,8 @@ namespace BreCalClient
|
||||
{
|
||||
Extensions.ParticipantType pType = (Extensions.ParticipantType) this.Times.ParticipantType;
|
||||
|
||||
// setting visibility
|
||||
|
||||
if (pType != Extensions.ParticipantType.MOORING)
|
||||
{
|
||||
this.labelATA.Visibility = Visibility.Hidden;
|
||||
@ -135,45 +147,37 @@ namespace BreCalClient
|
||||
}
|
||||
}
|
||||
|
||||
// setting en/dis-abled
|
||||
|
||||
if (this.Times.ParticipantId != App.Participant.Id)
|
||||
{
|
||||
this.buttonFixedOrder.IsEnabled = false;
|
||||
return; // if this is not "my" entry, there is no editing!
|
||||
}
|
||||
|
||||
if(pType == Extensions.ParticipantType.MOORING)
|
||||
{
|
||||
this.datePickerATA.IsEnabled = true;
|
||||
this.datePickerATD.IsEnabled = true;
|
||||
}
|
||||
|
||||
this.datePickerETABerth.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.datePickerETABerth_End.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.datePickerETDBerth.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Departure || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.datePickerETDBerth_End.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Departure || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.textBoxRemarks.IsReadOnly = false;
|
||||
|
||||
switch (pType)
|
||||
{
|
||||
case Extensions.ParticipantType.MOORING:
|
||||
case Extensions.ParticipantType.PORT_ADMINISTRATION:
|
||||
case Extensions.ParticipantType.TUG:
|
||||
this.datePickerETABerth.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.datePickerETABerth_End.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.datePickerETDBerth.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Departure || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.datePickerETDBerth_End.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Departure || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.datePickerLockTime.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.datePickerZoneEntry.IsEnabled = false;
|
||||
this.textBoxRemarks.IsEnabled = true;
|
||||
this.datePickerATA.IsEnabled = true;
|
||||
this.datePickerATD.IsEnabled = true;
|
||||
break;
|
||||
case Extensions.ParticipantType.PILOT:
|
||||
this.datePickerETABerth.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.datePickerETABerth_End.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.datePickerETDBerth.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Departure || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.datePickerETDBerth_End.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Departure || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.datePickerLockTime.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival || ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.datePickerZoneEntry.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.textBoxRemarks.IsEnabled = true;
|
||||
case Extensions.ParticipantType.PORT_ADMINISTRATION:
|
||||
this.datePickerLockTime.IsEnabled = true;
|
||||
break;
|
||||
case Extensions.ParticipantType.TUG:
|
||||
case Extensions.ParticipantType.PILOT:
|
||||
this.datePickerZoneEntry.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
this.buttonOK.IsEnabled = true;
|
||||
CheckOKButton();
|
||||
|
||||
}
|
||||
|
||||
private void SetLockButton(bool newValue)
|
||||
@ -182,14 +186,26 @@ namespace BreCalClient
|
||||
{
|
||||
this.Times.EtaBerthFixed = true;
|
||||
this.imageFixedOrder.Source = new BitmapImage(new Uri(@"pack://application:,,,/Resources/lock.png", UriKind.RelativeOrAbsolute));
|
||||
this.buttonFixedOrder.ToolTip = BreCalClient.Resources.Resources.textTooltipUnSetFixedOrder;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Times.EtaBerthFixed = false;
|
||||
this.imageFixedOrder.Source = new BitmapImage(new Uri(@"pack://application:,,,/Resources/lock_open.png", UriKind.RelativeOrAbsolute));
|
||||
this.buttonFixedOrder.ToolTip = BreCalClient.Resources.Resources.textTooltipSetFixedOrder;
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckOKButton()
|
||||
{
|
||||
Extensions.ParticipantType pType = (Extensions.ParticipantType)this.Times.ParticipantType;
|
||||
if (pType != Extensions.ParticipantType.PORT_ADMINISTRATION)
|
||||
this.buttonOK.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival) ?
|
||||
this.datePickerETABerth.Value.HasValue : this.datePickerETDBerth.Value.HasValue;
|
||||
else
|
||||
this.buttonOK.IsEnabled = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region clear value event handler
|
||||
@ -235,6 +251,6 @@ namespace BreCalClient
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
xmlns:local="clr-namespace:BreCalClient"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W1Left}" Top="{local:SettingBinding W1Top}"
|
||||
Title="{x:Static p:Resources.textEditTimes}" Loaded="Window_Loaded" Height="295" Width="500" >
|
||||
Title="{x:Static p:Resources.textEditTimes}" Loaded="Window_Loaded" Height="295" Width="500" ResizeMode="CanResizeWithGrip" >
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width=".3*" />
|
||||
@ -20,7 +20,7 @@
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="28" />
|
||||
<RowDefinition Height="56" />
|
||||
<RowDefinition Height="56" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="28" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
<ColumnDefinition Width=".5*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<xctk:DateTimePicker Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerOperationStart" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False">
|
||||
<xctk:DateTimePicker Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerOperationStart" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False" ValueChanged="datePickerOperationStart_ValueChanged">
|
||||
<xctk:DateTimePicker.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationStart" Click="contextMenuItemClearOperationStart_Click" >
|
||||
@ -69,7 +69,7 @@
|
||||
<ColumnDefinition Width=".5*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<xctk:DateTimePicker Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerOperationEnd" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False">
|
||||
<xctk:DateTimePicker Grid.Row="0" Grid.Column="0" Margin="2" Name="datePickerOperationEnd" Format="Custom" FormatString="dd.MM. yyyy HH:mm" IsEnabled="False" ValueChanged="datePickerOperationEnd_ValueChanged">
|
||||
<xctk:DateTimePicker.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Header="{x:Static p:Resources.textClearValue}" Name="contextMenuItemClearOperationEnd" Click="contextMenuItemClearOperationEnd_Click" >
|
||||
@ -112,8 +112,8 @@
|
||||
</ContextMenu>
|
||||
</ComboBox.ContextMenu>
|
||||
</ComboBox>
|
||||
<TextBox Grid.Row="4" Grid.Column="1" Margin="2" Name="textBoxBerthRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" IsEnabled="False" MaxLength="512" />
|
||||
<TextBox Grid.Row="5" Grid.Column="1" Margin="2" Name="textBoxRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" IsEnabled="False" MaxLength="512" />
|
||||
<TextBox Grid.Row="4" Grid.Column="1" Margin="2" Name="textBoxBerthRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" IsReadOnly="True" MaxLength="512" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
<TextBox Grid.Row="5" Grid.Column="1" Margin="2" Name="textBoxRemarks" TextWrapping="Wrap" AcceptsReturn="True" SpellCheck.IsEnabled="True" AcceptsTab="False" IsReadOnly="True" MaxLength="512" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
|
||||
<StackPanel Grid.Row="6" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Width= "80" Margin="2" Content="{x:Static p:Resources.textOK}" x:Name="buttonOK" Click="buttonOK_Click" IsEnabled="False"/>
|
||||
<Button Width="80" Margin="2" Content="{x:Static p:Resources.textCancel}" x:Name="buttonCancel" Click="buttonCancel_Click"/>
|
||||
|
||||
@ -76,6 +76,16 @@ namespace BreCalClient
|
||||
this.comboBoxPierside.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
private void datePickerOperationStart_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
this.CheckOKButton();
|
||||
}
|
||||
|
||||
private void datePickerOperationEnd_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
this.CheckOKButton();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
@ -134,9 +144,15 @@ namespace BreCalClient
|
||||
this.datePickerOperationEnd_End.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Departure) || (ShipcallModel.Shipcall?.Type == ShipcallType.Shifting);
|
||||
this.comboBoxBerth.IsEnabled = ShipcallModel.Shipcall?.Type == ShipcallType.Arrival;
|
||||
this.comboBoxPierside.IsEnabled = ShipcallModel.Shipcall?.Type == ShipcallType.Arrival;
|
||||
this.textBoxBerthRemarks.IsEnabled = ShipcallModel.Shipcall?.Type == ShipcallType.Arrival;
|
||||
this.textBoxRemarks.IsEnabled = true;
|
||||
this.buttonOK.IsEnabled = true;
|
||||
this.textBoxBerthRemarks.IsReadOnly = ShipcallModel.Shipcall?.Type != ShipcallType.Arrival;
|
||||
this.textBoxRemarks.IsReadOnly = false;
|
||||
this.CheckOKButton();
|
||||
}
|
||||
|
||||
private void CheckOKButton()
|
||||
{
|
||||
this.buttonOK.IsEnabled = (ShipcallModel.Shipcall?.Type == ShipcallType.Arrival) ? this.datePickerOperationStart.Value.HasValue :
|
||||
this.datePickerOperationEnd.Value.HasValue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
71
src/BreCalClient/EnumHelper.cs
Normal file
71
src/BreCalClient/EnumHelper.cs
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2024- schick Informatik
|
||||
// Description: Helpers to display localized Enum values in Comboboxes
|
||||
// https://stackoverflow.com/questions/29658721/enum-in-wpf-comboxbox-with-localized-names
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace BreCalClient
|
||||
{
|
||||
|
||||
#region class EnumToStringConverter
|
||||
|
||||
public sealed class EnumToStringConverter : IValueConverter
|
||||
{
|
||||
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null)
|
||||
{ return null; }
|
||||
|
||||
return Resources.Resources.ResourceManager.GetString(value.ToString() ?? "");
|
||||
}
|
||||
|
||||
public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
string str = (string)value;
|
||||
|
||||
foreach (object enumValue in Enum.GetValues(targetType))
|
||||
{
|
||||
if (str == Resources.Resources.ResourceManager.GetString(enumValue.ToString() ?? ""))
|
||||
{ return enumValue; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region class EnumerateExtension
|
||||
|
||||
public sealed class EnumerateExtension : MarkupExtension
|
||||
{
|
||||
public Type Type { get; set; }
|
||||
|
||||
public EnumerateExtension(Type type)
|
||||
{
|
||||
this.Type = type;
|
||||
}
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
string[] names = Enum.GetNames(Type);
|
||||
|
||||
// skip value "0" == "Unknown" (we dont want this selectable in the Combobox)
|
||||
// NOTE: This will only work in the future if the first element is always "undefined" aka unused
|
||||
|
||||
string[] values = new string[names.Length - 1];
|
||||
for (int i = 0; i < names.Length - 1; i++)
|
||||
{
|
||||
values[i] = Resources.Resources.ResourceManager.GetString(names[i + 1]) ?? names[i];
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@ -80,7 +80,12 @@ namespace BreCalClient
|
||||
{
|
||||
if(string.IsNullOrEmpty(value)) return value;
|
||||
if (value.Length <= maxLength) return value;
|
||||
if (value.Length > (maxLength + 1)) return $"{value[..maxLength]}..";
|
||||
if (value.Length > (maxLength + 1))
|
||||
{
|
||||
int i = maxLength - 2;
|
||||
for (; (i > 0) && !(char.IsWhiteSpace(value[i])); i--) ; // try to put the "..." at a word break
|
||||
return value.Substring(0, i) + " ...";
|
||||
}
|
||||
return value[..maxLength];
|
||||
}
|
||||
|
||||
|
||||
@ -14,19 +14,26 @@
|
||||
<RowDefinition Height="25" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width=".25*" />
|
||||
<ColumnDefinition Width=".25*" />
|
||||
<ColumnDefinition Width=".25*" />
|
||||
<ColumnDefinition Width=".25*" />
|
||||
<ColumnDefinition Width=".2*" />
|
||||
<ColumnDefinition Width=".2*" />
|
||||
<ColumnDefinition Width=".2*" />
|
||||
<ColumnDefinition Width=".2*" />
|
||||
<ColumnDefinition Width=".2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" FontSize="10" FontWeight="DemiBold" Text="{x:Static p:Resources.textShip}" VerticalAlignment="Center" Foreground="Gray" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="10" FontWeight="DemiBold" Text="{x:Static p:Resources.textTimestamp}" VerticalAlignment="Center" Foreground="Gray"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="2" FontSize="10" FontWeight="DemiBold" Text="{x:Static p:Resources.textOperation}" VerticalAlignment="Center" Foreground="Gray"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="3" FontSize="10" FontWeight="DemiBold" Text="{x:Static p:Resources.textParticipant}" VerticalAlignment="Center" Foreground="Gray"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" x:Name="textBlockShip" FontWeight="DemiBold" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" x:Name="textBlockTimestamp" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" x:Name="textBlockOperation" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="3" x:Name="textBlockParticipant" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="10" FontWeight="DemiBold" VerticalAlignment="Center" x:Name="textBlockShipcallType" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="2" FontSize="10" FontWeight="DemiBold" Text="{x:Static p:Resources.textTimestamp}" VerticalAlignment="Center" Foreground="Gray"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="3" FontSize="10" FontWeight="DemiBold" Text="{x:Static p:Resources.textOperation}" VerticalAlignment="Center" Foreground="Gray"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="4" FontSize="10" FontWeight="DemiBold" Text="{x:Static p:Resources.textParticipant}" VerticalAlignment="Center" Foreground="Gray"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" x:Name="textBlockShip" FontWeight="DemiBold">
|
||||
<Hyperlink Click="textBlockShip_Click">
|
||||
<TextBlock x:Name="hyperLinkShip" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" x:Name="textBlockEta" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="2" x:Name="textBlockTimestamp" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="3" x:Name="textBlockOperation" />
|
||||
<TextBlock Grid.Row="1" Grid.Column="4" x:Name="textBlockParticipant" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
using BreCalClient.misc.Model;
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace BreCalClient
|
||||
@ -12,16 +13,26 @@ namespace BreCalClient
|
||||
/// </summary>
|
||||
public partial class HistoryControl : UserControl
|
||||
{
|
||||
public HistoryControl(string ship, History history)
|
||||
private readonly History _history;
|
||||
public event Action<int>? HistorySelected;
|
||||
|
||||
public HistoryControl(string ship, History history, string callType, string etaetd)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_history = history;
|
||||
this.textBlockOperation.Text = $"{history.Operation} on {history.Type}";
|
||||
this.textBlockShip.Text = ship;
|
||||
this.hyperLinkShip.Text = ship;
|
||||
|
||||
if(BreCalLists.ParticipantLookupDict.ContainsKey(history.ParticipantId))
|
||||
this.textBlockParticipant.Text = BreCalLists.ParticipantLookupDict[history.ParticipantId].Name;
|
||||
this.textBlockTimestamp.Text = history.Timestamp.ToString();
|
||||
this.textBlockEta.Text = etaetd;
|
||||
this.textBlockShipcallType.Text = callType;
|
||||
}
|
||||
|
||||
private void textBlockShip_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
this.HistorySelected?.Invoke(_history.ShipcallId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,17 @@
|
||||
<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto" Margin="2">
|
||||
<StackPanel x:Name="stackPanel"/>
|
||||
</ScrollViewer>
|
||||
<Button x:Name="buttonClose" Click="buttonClose_Click" Content="{x:Static p:Resources.textClose}" Width="80" Margin="2" Grid.Row="1" HorizontalAlignment="Right" />
|
||||
<Grid Grid.Row="1" Grid.Column="0" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="22" />
|
||||
<ColumnDefinition Width="80" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width=".2*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<CheckBox x:Name="checkboxMyOwnOnly" VerticalContentAlignment="Center" Grid.Column="0" Margin="2" Checked="checkboxMyOwnOnly_Checked" Unchecked="checkboxMyOwnOnly_Checked" />
|
||||
<Label Content="{x:Static p:Resources.textMineOnly}" Grid.Column="1" />
|
||||
<Button x:Name="buttonClose" Click="buttonClose_Click" Content="{x:Static p:Resources.textClose}" Width="80" Margin="2" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Right" />
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@ -4,9 +4,14 @@
|
||||
|
||||
using BreCalClient.misc.Api;
|
||||
using BreCalClient.misc.Model;
|
||||
using log4net;
|
||||
using log4net.Core;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Printing;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace BreCalClient
|
||||
{
|
||||
@ -19,6 +24,13 @@ namespace BreCalClient
|
||||
|
||||
private readonly ConcurrentDictionary<int, ShipcallControlModel> _shipcalls;
|
||||
private readonly StaticApi _staticApi;
|
||||
private readonly static ILog _log = LogManager.GetLogger(typeof(HistoryDialog));
|
||||
|
||||
#endregion
|
||||
|
||||
#region delegate/event to react to history item selection
|
||||
|
||||
public event Action<int>? HistoryItemSelected;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -37,6 +49,7 @@ namespace BreCalClient
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
RefreshHistory();
|
||||
}
|
||||
|
||||
@ -45,6 +58,12 @@ namespace BreCalClient
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void checkboxMyOwnOnly_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
RefreshHistory();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
@ -52,30 +71,80 @@ namespace BreCalClient
|
||||
private async void RefreshHistory()
|
||||
{
|
||||
List<History> allHistories = new();
|
||||
foreach (int shipcall_id in _shipcalls.Keys)
|
||||
|
||||
try
|
||||
{
|
||||
List<History> shipcallHistory = await _staticApi.HistoryGetAsync(shipcall_id);
|
||||
System.Diagnostics.Trace.WriteLine($"{shipcallHistory.Count} history elements loaded for shipcall {shipcall_id}");
|
||||
allHistories.AddRange( shipcallHistory );
|
||||
foreach (int shipcall_id in _shipcalls.Keys)
|
||||
{
|
||||
List<History> shipcallHistory = await _staticApi.HistoryGetAsync(shipcall_id);
|
||||
System.Diagnostics.Trace.WriteLine($"{shipcallHistory.Count} history elements loaded for shipcall {shipcall_id}");
|
||||
allHistories.AddRange(shipcallHistory);
|
||||
}
|
||||
|
||||
this.stackPanel.Children.Clear();
|
||||
|
||||
// sort all entries
|
||||
allHistories.Sort((x, y) => { return y.Timestamp.CompareTo(x.Timestamp); });
|
||||
|
||||
EnumToStringConverter enumToStringConverter = new();
|
||||
|
||||
// create controls for all entries
|
||||
foreach (History history in allHistories)
|
||||
{
|
||||
if (FilterShipcall(history.ShipcallId)) continue;
|
||||
string shipname = "";
|
||||
Ship? ship = this._shipcalls[history.ShipcallId].Ship;
|
||||
if (ship != null)
|
||||
shipname = ship.Name;
|
||||
string etaetd = "", calltype = "";
|
||||
if (_shipcalls.ContainsKey(history.ShipcallId))
|
||||
{
|
||||
etaetd = _shipcalls[history.ShipcallId].GetETAETD();
|
||||
if (_shipcalls[history.ShipcallId].Shipcall != null)
|
||||
{
|
||||
ShipcallType? type = _shipcalls[history.ShipcallId].Shipcall?.Type;
|
||||
if (type != null) calltype = (string)(enumToStringConverter.Convert(type ?? ShipcallType.Undefined, typeof(ShipcallType), new(), System.Globalization.CultureInfo.CurrentCulture) ?? "");
|
||||
}
|
||||
}
|
||||
|
||||
HistoryControl hc = new(shipname, history, calltype, etaetd);
|
||||
hc.HistorySelected += (x) => { HistoryItemSelected?.Invoke(x); }; // bubble event
|
||||
this.stackPanel.Children.Add(hc);
|
||||
}
|
||||
|
||||
Mouse.OverrideCursor = null;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Here we rather not show a dialog box since it may confuse the user
|
||||
_log.Error(e.ToString());
|
||||
}
|
||||
|
||||
// sort all entries
|
||||
allHistories.Sort((x, y) => { return y.Timestamp.CompareTo(x.Timestamp); });
|
||||
}
|
||||
|
||||
// create controls for all entries
|
||||
foreach (History history in allHistories)
|
||||
bool FilterShipcall(int shipcallId)
|
||||
{
|
||||
bool result = true;
|
||||
if (shipcallId < 0) return result;
|
||||
if(_shipcalls.TryGetValue(shipcallId, out ShipcallControlModel? scm))
|
||||
{
|
||||
string shipname = "";
|
||||
Ship? ship = this._shipcalls[history.ShipcallId].Ship;
|
||||
if (ship != null)
|
||||
shipname = ship.Name;
|
||||
HistoryControl hc = new(shipname, history);
|
||||
this.stackPanel.Children.Add(hc);
|
||||
}
|
||||
if(this.checkboxMyOwnOnly.IsChecked ?? false)
|
||||
{
|
||||
foreach(ParticipantAssignment p in scm.AssignedParticipants.Values)
|
||||
{
|
||||
if (p.ParticipantId.Equals(App.Participant.Id)) return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,6 +116,7 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="26" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="100" />
|
||||
@ -150,10 +151,15 @@
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="11"/>
|
||||
<StatusBarItem Grid.Column="12">
|
||||
<Button x:Name="buttonManualRefresh" Width="20" Click="buttonManualRefresh_Click" ToolTip="{x:Static p:Resources.textTriggerManualRefresh}">
|
||||
<Image Source="./Resources/nav_refresh_green.png"/>
|
||||
</Button>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="13">
|
||||
<TextBlock x:Name="labelLatestUpdate" />
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="13"/>
|
||||
<StatusBarItem Grid.Column="14">
|
||||
<Separator Grid.Column="14"/>
|
||||
<StatusBarItem Grid.Column="15">
|
||||
<ProgressBar Name="generalProgressStatus" Width="90" Height="16" Foreground="LightGray"/>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
|
||||
@ -22,6 +22,7 @@ using Newtonsoft.Json;
|
||||
using Polly;
|
||||
using System.Net.Http;
|
||||
using System.Net;
|
||||
using System.Windows.Input;
|
||||
|
||||
|
||||
namespace BreCalClient
|
||||
@ -37,7 +38,8 @@ namespace BreCalClient
|
||||
|
||||
#region Fields
|
||||
|
||||
private static Int32 _uiUpdateRunning = 0;
|
||||
//private static int _uiUpdateRunning = 0;
|
||||
private static SemaphoreSlim uiLock = new SemaphoreSlim(1);
|
||||
|
||||
private Credentials? _credentials;
|
||||
|
||||
@ -96,9 +98,10 @@ namespace BreCalClient
|
||||
var jitterer = new Random();
|
||||
|
||||
var retryPolicy =
|
||||
Policy.Handle<HttpRequestException>()
|
||||
.OrResult<RestSharp.RestResponse>(resp => resp.StatusCode == HttpStatusCode.Unauthorized)
|
||||
.WaitAndRetryAsync(3,
|
||||
// Policy.Handle<HttpRequestException>()
|
||||
Policy.HandleResult<RestSharp.RestResponse>(resp => resp.StatusCode == HttpStatusCode.Unauthorized)
|
||||
//.OrResult<RestSharp.RestResponse>
|
||||
.WaitAndRetryAsync(1,
|
||||
retryAttempt =>
|
||||
{
|
||||
var calculatedDelayInMilliseconds = Math.Pow(2, retryAttempt) * 1000;
|
||||
@ -113,6 +116,7 @@ namespace BreCalClient
|
||||
Trace.WriteLine("token refreshed");
|
||||
});
|
||||
RetryConfiguration.AsyncRetryPolicy = retryPolicy;
|
||||
|
||||
this.generalProgressStatus.Maximum = PROGRESS_STEPS;
|
||||
}
|
||||
|
||||
@ -160,6 +164,7 @@ namespace BreCalClient
|
||||
{
|
||||
if (_loginResult.Id > 0)
|
||||
{
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
this.busyIndicator.IsBusy = false;
|
||||
this._userApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
||||
this._shipcallApi.Configuration.ApiKey["Authorization"] = _loginResult.Token;
|
||||
@ -233,7 +238,7 @@ namespace BreCalClient
|
||||
NewWithModel(null);
|
||||
}
|
||||
|
||||
private void NewWithModel(ShipcallControlModel? model)
|
||||
private async void NewWithModel(ShipcallControlModel? model)
|
||||
{
|
||||
EditShipcallControl esc = new()
|
||||
{
|
||||
@ -248,7 +253,9 @@ namespace BreCalClient
|
||||
// create UI & save new dialog model
|
||||
if (esc.ShipcallModel.Shipcall != null)
|
||||
{
|
||||
await uiLock.WaitAsync();
|
||||
this.UpdateUI();
|
||||
uiLock.Release();
|
||||
|
||||
esc.ShipcallModel.Shipcall?.Participants.Clear();
|
||||
foreach (ParticipantAssignment pa in esc.ShipcallModel.AssignedParticipants.Values)
|
||||
@ -269,9 +276,13 @@ namespace BreCalClient
|
||||
// if this was an arrival, create the matching departure call and open it
|
||||
if (esc.ShipcallModel.Shipcall?.Type == ShipcallType.Arrival)
|
||||
{
|
||||
ShipcallControlModel scmOut = new();
|
||||
scmOut.Shipcall = new();
|
||||
scmOut.Shipcall.Type = ShipcallType.Departure;
|
||||
ShipcallControlModel scmOut = new()
|
||||
{
|
||||
Shipcall = new()
|
||||
{
|
||||
Type = ShipcallType.Departure
|
||||
}
|
||||
};
|
||||
scmOut.Shipcall.ShipId = esc.ShipcallModel.Shipcall.ShipId;
|
||||
scmOut.Ship = esc.ShipcallModel.Ship;
|
||||
DateTime eta = esc.ShipcallModel.Shipcall?.Eta ?? DateTime.Now;
|
||||
@ -284,7 +295,11 @@ namespace BreCalClient
|
||||
foreach(ParticipantType pType in esc.ShipcallModel.AssignedParticipants.Keys)
|
||||
scmOut.AssignedParticipants[pType] = esc.ShipcallModel.AssignedParticipants[pType];
|
||||
}
|
||||
NewWithModel(scmOut);
|
||||
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
NewWithModel(scmOut);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,8 +307,10 @@ namespace BreCalClient
|
||||
|
||||
private void buttonInfo_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AboutDialog ad = new();
|
||||
ad.LoginResult = this._loginResult;
|
||||
AboutDialog ad = new()
|
||||
{
|
||||
LoginResult = this._loginResult
|
||||
};
|
||||
ad.ChangePasswordRequested += async (oldPw, newPw) =>
|
||||
{
|
||||
if (_loginResult != null)
|
||||
@ -332,10 +349,12 @@ namespace BreCalClient
|
||||
this.FilterShipcalls();
|
||||
}
|
||||
|
||||
private void SearchFilterControl_SearchFilterChanged()
|
||||
private async void SearchFilterControl_SearchFilterChanged()
|
||||
{
|
||||
this.FilterShipcalls();
|
||||
await uiLock.WaitAsync();
|
||||
this.UpdateUI();
|
||||
uiLock.Release();
|
||||
}
|
||||
|
||||
private void checkboxShowCancelledCalls_Checked(object sender, RoutedEventArgs e)
|
||||
@ -344,11 +363,13 @@ namespace BreCalClient
|
||||
this.SearchFilterControl_SearchFilterChanged();
|
||||
}
|
||||
|
||||
private void comboBoxSortOrder_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||
private async void comboBoxSortOrder_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||
{
|
||||
_sortOrder = (Extensions.SortOrder) this.comboBoxSortOrder.SelectedIndex;
|
||||
this.FilterShipcalls();
|
||||
await uiLock.WaitAsync();
|
||||
this.UpdateUI();
|
||||
uiLock.Release();
|
||||
}
|
||||
|
||||
private void buttonHistory_Click(object sender, RoutedEventArgs e)
|
||||
@ -357,6 +378,11 @@ namespace BreCalClient
|
||||
{
|
||||
_historyDialog = new HistoryDialog(_allShipcallsDict, _staticApi);
|
||||
_historyDialog.Closed += (sender, e) => { this._historyDialog = null; };
|
||||
_historyDialog.HistoryItemSelected += (x) =>
|
||||
{
|
||||
if(_allShipCallsControlDict.ContainsKey(x))
|
||||
_allShipCallsControlDict[x].BringIntoView();
|
||||
};
|
||||
_historyDialog.Show();
|
||||
}
|
||||
else
|
||||
@ -365,6 +391,13 @@ namespace BreCalClient
|
||||
}
|
||||
}
|
||||
|
||||
private void buttonManualRefresh_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_refreshImmediately = true; // set flag to avoid timer loop termination
|
||||
_tokenSource.Cancel(); // force timer loop end
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region network operations
|
||||
@ -421,6 +454,7 @@ namespace BreCalClient
|
||||
{
|
||||
labelGeneralStatus.Text = $"Connection {ConnectionStatus.SUCCESSFUL}";
|
||||
labelLatestUpdate.Text = $"Last update: {DateTime.Now.ToLongTimeString()}";
|
||||
labelStatusBar.Text = "";
|
||||
generalProgressStatus.Value = 0;
|
||||
}));
|
||||
}
|
||||
@ -438,49 +472,68 @@ namespace BreCalClient
|
||||
}
|
||||
}
|
||||
|
||||
if (shipcalls != null)
|
||||
try
|
||||
{
|
||||
foreach (Shipcall shipcall in shipcalls)
|
||||
{
|
||||
// load times for each shipcall
|
||||
List<Times> currentTimes = await _timesApi.TimesGetAsync(shipcall.Id);
|
||||
|
||||
if(!_allShipcallsDict.ContainsKey(shipcall.Id))
|
||||
if (shipcalls != null)
|
||||
{
|
||||
foreach (Shipcall shipcall in shipcalls)
|
||||
{
|
||||
// add entry
|
||||
ShipcallControlModel scm = new()
|
||||
// load times for each shipcall
|
||||
List<Times> currentTimes = await _timesApi.TimesGetAsync(shipcall.Id);
|
||||
|
||||
if (!_allShipcallsDict.ContainsKey(shipcall.Id))
|
||||
{
|
||||
Shipcall = shipcall,
|
||||
Times = currentTimes
|
||||
};
|
||||
this.AddShipcall(scm);
|
||||
// add entry
|
||||
ShipcallControlModel scm = new()
|
||||
{
|
||||
Shipcall = shipcall,
|
||||
Times = currentTimes
|
||||
};
|
||||
this.AddShipcall(scm);
|
||||
}
|
||||
else
|
||||
{
|
||||
// update entry
|
||||
_allShipcallsDict[shipcall.Id].Shipcall = shipcall;
|
||||
_allShipcallsDict[shipcall.Id].Times = currentTimes;
|
||||
UpdateShipcall(_allShipcallsDict[shipcall.Id]);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
List<int> existingIds = new(this._allShipcallsDict.Keys);
|
||||
|
||||
foreach (int existingId in existingIds)
|
||||
{
|
||||
// update entry
|
||||
_allShipcallsDict[shipcall.Id].Shipcall = shipcall;
|
||||
_allShipcallsDict[shipcall.Id].Times = currentTimes;
|
||||
UpdateShipcall(_allShipcallsDict[shipcall.Id]);
|
||||
if (shipcalls.Find(s => s.Id == existingId) == null) // the model is no longer in the search result
|
||||
{
|
||||
this.RemoveShipcall(existingId);
|
||||
}
|
||||
}
|
||||
|
||||
this.FilterShipcalls();
|
||||
await uiLock.WaitAsync();
|
||||
this.UpdateUI();
|
||||
}
|
||||
|
||||
List<int> 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();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_log.Error(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
uiLock.Release();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
double interval = (double) SHIPCALL_UPDATE_INTERVAL_SECONDS / PROGRESS_STEPS;
|
||||
|
||||
|
||||
//if (Interlocked.CompareExchange(ref _uiUpdateRunning, 1, 0) == 1) // do not restart progress unless UI update has completed
|
||||
// await Task.Delay(TimeSpan.FromSeconds(interval));
|
||||
|
||||
System.Diagnostics.Trace.WriteLine("restarting refresh countdown");
|
||||
for (int i = 0; i < PROGRESS_STEPS; i++)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(interval), _tokenSource.Token);
|
||||
@ -585,6 +638,8 @@ namespace BreCalClient
|
||||
else
|
||||
{
|
||||
searchPastDays = 0;
|
||||
if (sfm.EtaFrom == null)
|
||||
sfm.EtaFrom = DateTime.Now.AddDays(-2);
|
||||
}
|
||||
|
||||
this._visibleControlModels.Clear();
|
||||
@ -710,7 +765,13 @@ namespace BreCalClient
|
||||
if (x.Shipcall == null) return 0;
|
||||
if (y.Shipcall == null) return 0;
|
||||
DateTime xDate = (x.Shipcall.Type == ShipcallType.Arrival) ? x.Eta ?? DateTime.Now : x.Etd ?? DateTime.Now;
|
||||
Times? xTimes = x.GetTimesForParticipantType(ParticipantType.AGENCY);
|
||||
if(xTimes != null)
|
||||
xDate = (x.Shipcall.Type == ShipcallType.Arrival) ? xTimes.EtaBerth ?? DateTime.Now : xTimes.EtdBerth ?? DateTime.Now;
|
||||
DateTime yDate = (y.Shipcall.Type == ShipcallType.Arrival) ? y.Eta ?? DateTime.Now : y.Etd ?? DateTime.Now;
|
||||
Times? yTimes = y.GetTimesForParticipantType(ParticipantType.AGENCY);
|
||||
if (yTimes != null)
|
||||
yDate = (y.Shipcall.Type == ShipcallType.Arrival) ? yTimes.EtaBerth ?? DateTime.Now : yTimes.EtdBerth ?? DateTime.Now;
|
||||
return DateTime.Compare(xDate, yDate);
|
||||
});
|
||||
break;
|
||||
@ -730,7 +791,7 @@ namespace BreCalClient
|
||||
|
||||
this.Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref _uiUpdateRunning, 1, 0) == 1) return;
|
||||
//if (Interlocked.CompareExchange(ref _uiUpdateRunning, 1, 0) == 1) return;
|
||||
|
||||
try
|
||||
{
|
||||
@ -750,9 +811,10 @@ namespace BreCalClient
|
||||
}
|
||||
finally
|
||||
{
|
||||
_uiUpdateRunning = 0;
|
||||
// _uiUpdateRunning = 0;
|
||||
}
|
||||
|
||||
Mouse.OverrideCursor = null;
|
||||
}));
|
||||
}
|
||||
|
||||
@ -955,6 +1017,6 @@ namespace BreCalClient
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ApplicationRevision>1</ApplicationRevision>
|
||||
<ApplicationVersion>1.2.0.1</ApplicationVersion>
|
||||
<ApplicationVersion>1.2.0.2</ApplicationVersion>
|
||||
<BootstrapperEnabled>True</BootstrapperEnabled>
|
||||
<Configuration>Debug</Configuration>
|
||||
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||
|
||||
@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>6.0</ApplicationVersion>
|
||||
<ApplicationRevision>10</ApplicationRevision>
|
||||
<ApplicationVersion>1.2.1.2</ApplicationVersion>
|
||||
<BootstrapperEnabled>False</BootstrapperEnabled>
|
||||
<Configuration>Release</Configuration>
|
||||
<CreateWebPageOnPublish>True</CreateWebPageOnPublish>
|
||||
|
||||
@ -4,8 +4,8 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.2.0.0</ApplicationVersion>
|
||||
<ApplicationRevision>2</ApplicationRevision>
|
||||
<ApplicationVersion>1.2.0.10</ApplicationVersion>
|
||||
<BootstrapperEnabled>True</BootstrapperEnabled>
|
||||
<Configuration>Debug</Configuration>
|
||||
<CreateDesktopShortcut>True</CreateDesktopShortcut>
|
||||
|
||||
48
src/BreCalClient/Properties/Settings.Designer.cs
generated
48
src/BreCalClient/Properties/Settings.Designer.cs
generated
@ -9,38 +9,38 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace BreCalClient.Properties {
|
||||
|
||||
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#1D751F")]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("#203864")]
|
||||
public string BG_COLOR {
|
||||
get {
|
||||
return ((string)(this["BG_COLOR"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("!!Bremen calling Testversion!!")]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("Bremen calling")]
|
||||
public string APP_TITLE {
|
||||
get {
|
||||
return ((string)(this["APP_TITLE"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("https://www.textbausteine.net/")]
|
||||
@ -49,7 +49,7 @@ namespace BreCalClient.Properties {
|
||||
return ((string)(this["LOGO_IMAGE_URL"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
@ -61,16 +61,16 @@ namespace BreCalClient.Properties {
|
||||
this["FilterCriteria"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("https://brecaldevel.bsmd-emswe.eu")]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("https://brecal.bsmd-emswe.eu")]
|
||||
public string API_URL {
|
||||
get {
|
||||
return ((string)(this["API_URL"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("800")]
|
||||
@ -82,7 +82,7 @@ namespace BreCalClient.Properties {
|
||||
this["Width"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("450")]
|
||||
@ -94,7 +94,7 @@ namespace BreCalClient.Properties {
|
||||
this["Height"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -106,7 +106,7 @@ namespace BreCalClient.Properties {
|
||||
this["Left"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -118,7 +118,7 @@ namespace BreCalClient.Properties {
|
||||
this["Top"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -130,7 +130,7 @@ namespace BreCalClient.Properties {
|
||||
this["W1Left"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -142,7 +142,7 @@ namespace BreCalClient.Properties {
|
||||
this["W1Top"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -154,7 +154,7 @@ namespace BreCalClient.Properties {
|
||||
this["W2Left"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -166,7 +166,7 @@ namespace BreCalClient.Properties {
|
||||
this["W2Top"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -178,7 +178,7 @@ namespace BreCalClient.Properties {
|
||||
this["W3Left"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -190,7 +190,7 @@ namespace BreCalClient.Properties {
|
||||
this["W3Top"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
@ -202,7 +202,7 @@ namespace BreCalClient.Properties {
|
||||
this["W4Left"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="BG_COLOR" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">#1D751F</Value>
|
||||
<Value Profile="(Default)">#203864</Value>
|
||||
</Setting>
|
||||
<Setting Name="APP_TITLE" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">!!Bremen calling Testversion!!</Value>
|
||||
<Value Profile="(Default)">Bremen calling</Value>
|
||||
</Setting>
|
||||
<Setting Name="LOGO_IMAGE_URL" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">https://www.textbausteine.net/</Value>
|
||||
@ -15,7 +15,7 @@
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="API_URL" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">https://brecaldevel.bsmd-emswe.eu</Value>
|
||||
<Value Profile="(Default)">https://brecal.bsmd-emswe.eu</Value>
|
||||
</Setting>
|
||||
<Setting Name="Width" Type="System.Double" Scope="User">
|
||||
<Value Profile="(Default)">800</Value>
|
||||
|
||||
82
src/BreCalClient/Resources/Resources.Designer.cs
generated
82
src/BreCalClient/Resources/Resources.Designer.cs
generated
@ -80,6 +80,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Incoming.
|
||||
/// </summary>
|
||||
public static string Arrival {
|
||||
get {
|
||||
return ResourceManager.GetString("Arrival", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
@ -200,6 +209,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Outgoing.
|
||||
/// </summary>
|
||||
public static string Departure {
|
||||
get {
|
||||
return ResourceManager.GetString("Departure", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
@ -240,6 +258,25 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
public static byte[] nav_refresh_green {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("nav_refresh_green", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Shifting.
|
||||
/// </summary>
|
||||
public static string Shifting {
|
||||
get {
|
||||
return ResourceManager.GetString("Shifting", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
@ -989,6 +1026,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Ships.
|
||||
/// </summary>
|
||||
public static string textShips {
|
||||
get {
|
||||
return ResourceManager.GetString("textShips", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show cancelled calls.
|
||||
/// </summary>
|
||||
@ -1061,6 +1107,33 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Set as a fixed order.
|
||||
/// </summary>
|
||||
public static string textTooltipSetFixedOrder {
|
||||
get {
|
||||
return ResourceManager.GetString("textTooltipSetFixedOrder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unset as a a fixed order.
|
||||
/// </summary>
|
||||
public static string textTooltipUnSetFixedOrder {
|
||||
get {
|
||||
return ResourceManager.GetString("textTooltipUnSetFixedOrder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Trigger a manual refresh of all shipcalls.
|
||||
/// </summary>
|
||||
public static string textTriggerManualRefresh {
|
||||
get {
|
||||
return ResourceManager.GetString("textTriggerManualRefresh", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Tug.
|
||||
/// </summary>
|
||||
@ -1240,6 +1313,15 @@ namespace BreCalClient.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Undefined.
|
||||
/// </summary>
|
||||
public static string Undefined {
|
||||
get {
|
||||
return ResourceManager.GetString("Undefined", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
|
||||
@ -472,4 +472,28 @@
|
||||
<data name="textFixedOrder" xml:space="preserve">
|
||||
<value>Als feste Bestellung vermerkt</value>
|
||||
</data>
|
||||
<data name="textTooltipSetFixedOrder" xml:space="preserve">
|
||||
<value>Als feste Bestellung vermerken</value>
|
||||
</data>
|
||||
<data name="textTooltipUnSetFixedOrder" xml:space="preserve">
|
||||
<value>Feste Bestellung zurücknehmen</value>
|
||||
</data>
|
||||
<data name="textTriggerManualRefresh" xml:space="preserve">
|
||||
<value>Manuelle Aktualisierung der Anläufe auslösen</value>
|
||||
</data>
|
||||
<data name="Arrival" xml:space="preserve">
|
||||
<value>Einkommend</value>
|
||||
</data>
|
||||
<data name="Departure" xml:space="preserve">
|
||||
<value>Ausgehend</value>
|
||||
</data>
|
||||
<data name="Shifting" xml:space="preserve">
|
||||
<value>Verholung</value>
|
||||
</data>
|
||||
<data name="Undefined" xml:space="preserve">
|
||||
<value>Unbekannt</value>
|
||||
</data>
|
||||
<data name="textShips" xml:space="preserve">
|
||||
<value>Schiffe</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -121,6 +121,9 @@
|
||||
<data name="add" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>add.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="Arrival" xml:space="preserve">
|
||||
<value>Incoming</value>
|
||||
</data>
|
||||
<data name="arrow_down_green" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>arrow_down_green.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
@ -157,6 +160,9 @@
|
||||
<data name="delete2" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>delete2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="Departure" xml:space="preserve">
|
||||
<value>Outgoing</value>
|
||||
</data>
|
||||
<data name="edit" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>edit.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
@ -169,6 +175,12 @@
|
||||
<data name="logo_bremen_calling" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>logo_bremen_calling.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="nav_refresh_green" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>nav_refresh_green.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="Shifting" xml:space="preserve">
|
||||
<value>Shifting</value>
|
||||
</data>
|
||||
<data name="ship2" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>ship2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
@ -418,6 +430,9 @@
|
||||
<data name="textShipLength" xml:space="preserve">
|
||||
<value>Ship length</value>
|
||||
</data>
|
||||
<data name="textShips" xml:space="preserve">
|
||||
<value>Ships</value>
|
||||
</data>
|
||||
<data name="textShowCancelledShipcalls" xml:space="preserve">
|
||||
<value>Show cancelled calls</value>
|
||||
</data>
|
||||
@ -442,6 +457,15 @@
|
||||
<data name="textTo" xml:space="preserve">
|
||||
<value>to</value>
|
||||
</data>
|
||||
<data name="textTooltipSetFixedOrder" xml:space="preserve">
|
||||
<value>Set as a fixed order</value>
|
||||
</data>
|
||||
<data name="textTooltipUnSetFixedOrder" xml:space="preserve">
|
||||
<value>Unset as a a fixed order</value>
|
||||
</data>
|
||||
<data name="textTriggerManualRefresh" xml:space="preserve">
|
||||
<value>Trigger a manual refresh of all shipcalls</value>
|
||||
</data>
|
||||
<data name="textTug" xml:space="preserve">
|
||||
<value>Tug</value>
|
||||
</data>
|
||||
@ -499,6 +523,9 @@
|
||||
<data name="umbrella_open" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>umbrella_open.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="Undefined" xml:space="preserve">
|
||||
<value>Undefined</value>
|
||||
</data>
|
||||
<data name="worker2" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>worker2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
|
||||
BIN
src/BreCalClient/Resources/nav_refresh_green.png
Normal file
BIN
src/BreCalClient/Resources/nav_refresh_green.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@ -5,9 +5,13 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:p = "clr-namespace:BreCalClient.Resources"
|
||||
xmlns:local="clr-namespace:BreCalClient"
|
||||
xmlns:api="clr-namespace:BreCalClient.misc.Model"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="56" d:DesignWidth="800" Loaded="UserControl_Loaded">
|
||||
<UserControl.Resources>
|
||||
<local:EnumToStringConverter x:Key="enumToStringConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28" />
|
||||
@ -63,7 +67,7 @@
|
||||
<Label Grid.Column="1" Content="{x:Static p:Resources.textTo}" />
|
||||
<DatePicker x:Name="datePickerETATo" Grid.Column="2" Margin="2" SelectedDateChanged="datePickerETATo_SelectedDateChanged" SelectedDate="{Binding Path=EtaTo}"/>
|
||||
</Grid>
|
||||
<xctk:CheckComboBox x:Name="comboBoxCategories" Grid.Column="4" Margin="2" ItemSelectionChanged="comboBoxCategories_ItemSelectionChanged" />
|
||||
<xctk:CheckComboBox x:Name="comboBoxCategories" Grid.Column="4" Margin="2" ItemSelectionChanged="comboBoxCategories_ItemSelectionChanged" ItemsSource="{local:Enumerate {x:Type api:ShipcallType}}" />
|
||||
<Grid Grid.Column="6" Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width=".5*" />
|
||||
|
||||
@ -72,7 +72,7 @@ namespace BreCalClient
|
||||
this.comboBoxAgencies.UnSelectAll();
|
||||
this.comboBoxBerths.UnSelectAll();
|
||||
this.comboBoxCategories.UnSelectAll();
|
||||
this.datePickerETAFrom.SelectedDate = null;
|
||||
this.datePickerETAFrom.SelectedDate = DateTime.Now.AddDays(-2);
|
||||
this.datePickerETATo.SelectedDate = null;
|
||||
this.textBoxSearch.Clear();
|
||||
this.upDownShiplengthFrom.Value = null;
|
||||
@ -101,13 +101,19 @@ namespace BreCalClient
|
||||
}
|
||||
if(sfm.Categories != null)
|
||||
{
|
||||
foreach(ShipcallType category in sfm.Categories)
|
||||
this.comboBoxCategories.SelectedItems.Add(category);
|
||||
EnumToStringConverter enumToStringConverter = new();
|
||||
foreach (ShipcallType category in sfm.Categories)
|
||||
{
|
||||
this.comboBoxCategories.SelectedItems.Add(enumToStringConverter.Convert(category, typeof(ShipcallControl), new object(), System.Globalization.CultureInfo.CurrentCulture));
|
||||
}
|
||||
}
|
||||
if (sfm.SearchString != null) this.textBoxSearch.Text = sfm.SearchString;
|
||||
this.upDownShiplengthFrom.Value = sfm.ShipLengthFrom;
|
||||
this.upDownShiplengthTo.Value = sfm.ShipLengthTo;
|
||||
this.datePickerETAFrom.SelectedDate = sfm.EtaFrom;
|
||||
if (sfm.EtaFrom != null)
|
||||
this.datePickerETAFrom.SelectedDate = sfm.EtaFrom;
|
||||
else
|
||||
this.datePickerETAFrom.SelectedDate = DateTime.Now.AddDays(-2);
|
||||
this.datePickerETATo.SelectedDate = sfm.EtaTo;
|
||||
this.checkBoxOwn.IsChecked = sfm.MineOnly;
|
||||
|
||||
@ -126,7 +132,7 @@ namespace BreCalClient
|
||||
|
||||
private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
this.comboBoxCategories.ItemsSource = Enum.GetValues(typeof(ShipcallType));
|
||||
|
||||
}
|
||||
|
||||
private void datePickerETAFrom_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
|
||||
@ -143,9 +149,15 @@ namespace BreCalClient
|
||||
|
||||
private void comboBoxCategories_ItemSelectionChanged(object sender, Xceed.Wpf.Toolkit.Primitives.ItemSelectionChangedEventArgs e)
|
||||
{
|
||||
EnumToStringConverter enumToStringConverter = new();
|
||||
|
||||
_model.Categories.Clear();
|
||||
foreach(ShipcallType category in comboBoxCategories.SelectedItems)
|
||||
_model.Categories.Add(category);
|
||||
foreach (string categoryString in comboBoxCategories.SelectedItems)
|
||||
{
|
||||
ShipcallType? type = (ShipcallType?)enumToStringConverter.ConvertBack(categoryString, typeof(ShipcallType), new object(), System.Globalization.CultureInfo.CurrentCulture);
|
||||
if(type != null)
|
||||
_model.Categories.Add(type.Value);
|
||||
}
|
||||
|
||||
SearchFilterChanged?.Invoke();
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:p = "clr-namespace:BreCalClient.Resources"
|
||||
xmlns:local="clr-namespace:BreCalClient"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W2Left}" Top="{local:SettingBinding W2Top}"
|
||||
mc:Ignorable="d" Left="{local:SettingBinding W2Left}" Top="{local:SettingBinding W2Top}" Title="{x:Static p:Resources.textShips}"
|
||||
Height="490" Width="800" ResizeMode="CanResize" Icon="Resources/containership.ico" Loaded="Window_Loaded">
|
||||
|
||||
<Grid>
|
||||
|
||||
@ -38,7 +38,7 @@ namespace BreCalClient
|
||||
this.dataGridShips.Initialize();
|
||||
this.dataGridShips.ItemsSource = BreCalLists.AllShips;
|
||||
|
||||
this.dataGridShips.CreateRequested += DataGridShips_CreateRequested; ;
|
||||
this.dataGridShips.CreateRequested += DataGridShips_CreateRequested;
|
||||
this.dataGridShips.EditRequested += DataGridShips_EditRequested;
|
||||
this.dataGridShips.DeleteRequested += DataGridShips_DeleteRequested;
|
||||
}
|
||||
@ -47,10 +47,15 @@ namespace BreCalClient
|
||||
{
|
||||
if (obj is ShipModel shipmodel)
|
||||
{
|
||||
if(this.ShipApi != null)
|
||||
await this.ShipApi.ShipDeleteAsync(shipmodel.Ship.Id);
|
||||
BreCalLists.Ships.Remove(shipmodel); // remove from "selectable" ships
|
||||
shipmodel.Ship.Deleted = true; // set deleted marker on working instance
|
||||
if (!shipmodel.Ship.Deleted)
|
||||
{
|
||||
if (this.ShipApi != null)
|
||||
await this.ShipApi.ShipDeleteAsync(shipmodel.Ship.Id);
|
||||
BreCalLists.Ships.Remove(shipmodel); // remove from "selectable" ships
|
||||
shipmodel.Ship.Deleted = true; // set deleted marker on working instance
|
||||
this.dataGridShips.ItemsSource = null;
|
||||
this.dataGridShips.ItemsSource = BreCalLists.AllShips;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,9 +88,9 @@ namespace BreCalClient
|
||||
}
|
||||
}
|
||||
|
||||
private void DataGridShips_CreateRequested()
|
||||
private async void DataGridShips_CreateRequested()
|
||||
{
|
||||
ShipModel shipModel = new ShipModel(new Ship());
|
||||
ShipModel shipModel = new(new Ship());
|
||||
EditShipDialog esd = new()
|
||||
{
|
||||
Ship = shipModel.Ship
|
||||
@ -96,11 +101,17 @@ namespace BreCalClient
|
||||
{
|
||||
try
|
||||
{
|
||||
this.ShipApi?.ShipsCreateAsync(shipModel.Ship);
|
||||
this.dataGridShips.ItemsSource = null;
|
||||
BreCalLists.AllShips.Add(shipModel);
|
||||
BreCalLists.Ships.Add(shipModel);
|
||||
this.dataGridShips.ItemsSource = BreCalLists.AllShips;
|
||||
if (this.ShipApi != null)
|
||||
{
|
||||
Id id = await this.ShipApi.ShipsCreateAsync(shipModel.Ship);
|
||||
shipModel.Ship.Id = id.VarId;
|
||||
this.dataGridShips.ItemsSource = null;
|
||||
BreCalLists.AllShips.Add(shipModel);
|
||||
BreCalLists.Ships.Add(shipModel);
|
||||
if(!BreCalLists.ShipLookupDict.TryAdd(id.VarId, shipModel))
|
||||
BreCalLists.ShipLookupDict[id.VarId] = shipModel;
|
||||
this.dataGridShips.ItemsSource = BreCalLists.AllShips;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<UserControl x:Class="BreCalClient.ShipcallControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:p = "clr-namespace:BreCalClient.Resources"
|
||||
xmlns:sets="clr-namespace:BreCalClient.Properties"
|
||||
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalDevelClient"
|
||||
mc:Ignorable="d"
|
||||
xmlns:db="clr-namespace:BreCalClient;assembly=BreCalClient"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="135" d:DesignWidth="800">
|
||||
<Border BorderBrush="LightGray" Margin="1" BorderThickness="1">
|
||||
<Grid>
|
||||
@ -45,7 +45,7 @@
|
||||
<ColumnDefinition Width="32" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Margin="2" Grid.Column="0" PreviewMouseUp="Image_PreviewMouseUp" x:Name="imageShipcallType" />
|
||||
<Label Grid.Column="1" FontSize="12" x:Name="labelShipName" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
<Label Grid.Column="1" FontSize="12" x:Name="labelShipName" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" PreviewMouseUp="Image_PreviewMouseUp">
|
||||
<TextBlock Name="textBlockShipName" />
|
||||
</Label>
|
||||
@ -89,23 +89,23 @@
|
||||
<Viewbox Grid.Row="6" Grid.Column="1" HorizontalAlignment="Left">
|
||||
<TextBlock x:Name="textBlockBerth" Padding="0" FontWeight="DemiBold" />
|
||||
</Viewbox>
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="1" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
<Label Grid.Row="0" Grid.Column="1" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelAgent" PreviewMouseUp="labelAgent_PreviewMouseUp"/>
|
||||
<Label Grid.Row="0" Grid.Column="2" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
<Label Grid.Row="0" Grid.Column="2" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelMooring" PreviewMouseUp="labelMooring_PreviewMouseUp"/>
|
||||
<Label Grid.Row="0" Grid.Column="3" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
<Label Grid.Row="0" Grid.Column="3" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPortAuthority" PreviewMouseUp="labelPortAuthority_PreviewMouseUp" />
|
||||
<Label Grid.Row="0" Grid.Column="4" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
<Label Grid.Row="0" Grid.Column="4" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelPilot" PreviewMouseUp="labelPilot_PreviewMouseUp"/>
|
||||
<Label Grid.Row="0" Grid.Column="5" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
<Label Grid.Row="0" Grid.Column="5" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTug" PreviewMouseUp="labelTug_PreviewMouseUp"/>
|
||||
<Label Grid.Row="0" Grid.Column="6" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
<Label Grid.Row="0" Grid.Column="6" Grid.RowSpan="1" FontSize="12" Content="- / -" Foreground="White" Background="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelTerminal" PreviewMouseUp="labelTerminal_PreviewMouseUp" />
|
||||
|
||||
|
||||
<!-- AGENCY -->
|
||||
<Border Grid.Row="2" Grid.Column="1" BorderThickness="1, 0, 0, 0" BorderBrush="{Binding Source={x:Static sets:Settings.Default}, Path=BG_COLOR}" Padding="3,0,0,0">
|
||||
<Grid Grid.Row="2" Grid.Column="1">
|
||||
@ -119,14 +119,18 @@
|
||||
<RowDefinition Height="14" />
|
||||
<RowDefinition Height=".5*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content = "ETA" x:Name="labelETAETDAgent" Padding="0" VerticalContentAlignment="Center" />
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
|
||||
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
|
||||
<Border Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="0,1,0,0" BorderBrush="Gray" >
|
||||
<Label Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
|
||||
</Border>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelAgencyETAETDValue" FontWeight="DemiBold"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Grid.RowSpan="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockAgencyRemarks" FontSize="10"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelAgencyBerth" Padding="0" VerticalContentAlignment="Center" FontSize="11" FontWeight="SemiBold" />
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textBerthRemarks}" Padding="0" VerticalAlignment="Top" TextWrapping="Wrap" FontSize="9"/>
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textRemarks}" Padding="0" VerticalAlignment="Top" TextWrapping="Wrap" FontSize="9"/>
|
||||
<TextBlock Grid.Row="3" Grid.Column="1" Grid.RowSpan="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockAgencyBerthRemarks" FontSize="10"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
@ -164,13 +168,16 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="20" />
|
||||
<RowDefinition Height="0" x:Name="lockTimeRowDefinition" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Grid.Row="0" Grid.Column="0" x:Name="labelETAETDPortAuthority" Content="ETA" Padding="0" VerticalContentAlignment="Center" />
|
||||
<Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Top" FontSize="9"/>
|
||||
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Top" FontSize="9"/>
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textLockTime}" VerticalContentAlignment="Center" Padding="0"/>
|
||||
<Label Grid.Row="1" Grid.Column="1" x:Name="labelPortAuthorityLockTime" VerticalContentAlignment="Center" Padding="0" />
|
||||
<Label Grid.Row="0" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelPortAuthorityETAETDValue" FontWeight="DemiBold"/>
|
||||
<Image Grid.Row="1" Grid.Column="0" x:Name="imagePortAuthorityLocked" VerticalAlignment="Top" Margin="0 20 0 0" HorizontalAlignment="Left" Source="./Resources/lock.png" Width="16" Height="16" ToolTip="{x:Static p:Resources.textFixedOrder}"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockPortAuthorityRemarks"/>
|
||||
<Image Grid.Row="2" Grid.Column="0" x:Name="imagePortAuthorityLocked" VerticalAlignment="Top" Margin="0 20 0 0" HorizontalAlignment="Left" Source="./Resources/lock.png" Width="16" Height="16" ToolTip="{x:Static p:Resources.textFixedOrder}"/>
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockPortAuthorityRemarks"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<!-- PILOT -->
|
||||
@ -226,9 +233,11 @@
|
||||
<Label Grid.Row="0" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" x:Name="labelOperationsStart" FontWeight="DemiBold"/>
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static p:Resources.textRemarks}" Padding="0" VerticalContentAlignment="Top" FontSize="9"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockTerminalRemarks" FontSize="10"/>
|
||||
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
|
||||
<Border BorderThickness="0,1,0,0" BorderBrush="Gray" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2">
|
||||
<Label Content="{x:Static p:Resources.textBerth}" Padding="0" VerticalContentAlignment="Center" FontSize="9"/>
|
||||
</Border>
|
||||
<Label Grid.Row="2" Grid.Column="1" HorizontalContentAlignment="Left" x:Name="labelTerminalBerth" Padding="0" VerticalContentAlignment="Center" FontSize="11" FontWeight="SemiBold" />
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textBerthRemarks}" TextWrapping="Wrap" Padding="0" VerticalAlignment="Top" FontSize="9"/>
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{x:Static p:Resources.textRemarks}" TextWrapping="Wrap" Padding="0" VerticalAlignment="Top" FontSize="9"/>
|
||||
<TextBlock Grid.Row="3" Grid.Column="1" Padding="0" TextWrapping="Wrap" VerticalAlignment="Top" x:Name="textBlockTerminalBerthRemarks" FontSize="10"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@ -28,6 +28,7 @@ namespace BreCalClient
|
||||
private static readonly ILog _log = LogManager.GetLogger(typeof(ShipcallControl));
|
||||
bool ataAdded = false;
|
||||
bool atdAdded = false;
|
||||
bool lockTimeAdded = false;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -213,13 +214,13 @@ namespace BreCalClient
|
||||
switch (this.ShipcallControlModel?.Shipcall?.Type)
|
||||
{
|
||||
case ShipcallType.Arrival: // incoming
|
||||
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/arrow_down_red.png"));
|
||||
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/arrow_down_red.png"));
|
||||
break;
|
||||
case ShipcallType.Departure: // outgoing
|
||||
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/arrow_up_blue.png"));
|
||||
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/arrow_up_blue.png"));
|
||||
break;
|
||||
case ShipcallType.Shifting: // shifting
|
||||
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/arrow_right_green.png"));
|
||||
this.imageShipcallType.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/arrow_right_green.png"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -227,14 +228,14 @@ namespace BreCalClient
|
||||
|
||||
switch(this.ShipcallControlModel?.LightMode)
|
||||
{
|
||||
case ShipcallControlModel.TrafficLightMode.GREEN:
|
||||
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/check.png"));
|
||||
case EvaluationType.Green:
|
||||
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/check.png"));
|
||||
break;
|
||||
case ShipcallControlModel.TrafficLightMode.YELLOW:
|
||||
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/sign_warning.png"));
|
||||
case EvaluationType.Yellow:
|
||||
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/sign_warning.png"));
|
||||
break;
|
||||
case ShipcallControlModel.TrafficLightMode.RED:
|
||||
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalDevelClient;component/Resources/delete2.png"));
|
||||
case EvaluationType.Red:
|
||||
this.imageEvaluation.Source = new BitmapImage(new Uri("pack://application:,,,/BreCalClient;component/Resources/delete2.png"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -251,22 +252,13 @@ namespace BreCalClient
|
||||
{
|
||||
if (this.ShipcallControlModel?.Shipcall?.Evaluation != null)
|
||||
{
|
||||
ShipcallControlModel.TrafficLightMode resultColor = (ShipcallControlModel.TrafficLightMode)(this.ShipcallControlModel?.Shipcall?.Evaluation ?? 0); // der nullable Operator hier ist so doof, die VS validation blickts einfach nicht
|
||||
switch (resultColor)
|
||||
this.Background = this.ShipcallControlModel.LightMode switch
|
||||
{
|
||||
//case ShipcallControlModel.TrafficLightMode.GREEN:
|
||||
// this.Background = Brushes.LightGreen;
|
||||
// break;
|
||||
case ShipcallControlModel.TrafficLightMode.YELLOW:
|
||||
this.Background = Brushes.LightYellow;
|
||||
break;
|
||||
case ShipcallControlModel.TrafficLightMode.RED:
|
||||
this.Background = new SolidColorBrush(Color.FromArgb(200, 255, 100, 100));
|
||||
break;
|
||||
default:
|
||||
this.Background = Brushes.Transparent;
|
||||
break;
|
||||
}
|
||||
// ShipcallControlModel.TrafficLightMode.GREEN => this.Background = Brushes.LightGreen,
|
||||
EvaluationType.Yellow => Brushes.LightYellow,
|
||||
EvaluationType.Red => new SolidColorBrush(Color.FromArgb(200, 255, 100, 100)),
|
||||
_ => Brushes.Transparent,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,6 +295,17 @@ namespace BreCalClient
|
||||
this.labelETAETDTerminal.Content = BreCalClient.Resources.Resources.textOperationsEnd;
|
||||
}
|
||||
|
||||
if((this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival) && (this.ShipcallControlModel?.Shipcall.TimeRefPoint != null))
|
||||
{
|
||||
int timeRefPointIndex = this.ShipcallControlModel?.Shipcall?.TimeRefPoint ?? 0;
|
||||
|
||||
this.labelETAETDAgent.Content = BreCalLists.TimeRefs[timeRefPointIndex];
|
||||
this.labelETAETDMooring.Content = BreCalLists.TimeRefs[timeRefPointIndex];
|
||||
this.labelETAETDPilot.Content = BreCalLists.TimeRefs[timeRefPointIndex];
|
||||
this.labelETAETDPortAuthority.Content = BreCalLists.TimeRefs[timeRefPointIndex];
|
||||
this.labelETAETDTug.Content = BreCalLists.TimeRefs[timeRefPointIndex];
|
||||
}
|
||||
|
||||
if (this.ShipcallControlModel != null)
|
||||
{
|
||||
|
||||
@ -311,8 +314,8 @@ namespace BreCalClient
|
||||
{
|
||||
this.labelAgencyBerth.Content = this.ShipcallControlModel?.GetBerthText(agencyTimes);
|
||||
this.labelAgencyETAETDValue.Content = agencyTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.textBlockAgencyRemarks.Text = agencyTimes.Remarks;
|
||||
this.textBlockAgencyBerthRemarks.Text = agencyTimes.BerthInfo;
|
||||
this.textBlockAgencyRemarks.Text = agencyTimes.Remarks.TruncateDots(50);
|
||||
this.textBlockAgencyBerthRemarks.Text = agencyTimes.BerthInfo.TruncateDots(50);
|
||||
this.textBlockDraft.Text = ShipcallControlModel?.Shipcall?.Draft?.ToString("N2");
|
||||
}
|
||||
else
|
||||
@ -325,22 +328,22 @@ namespace BreCalClient
|
||||
this.textBlockDraft.Text = "";
|
||||
}
|
||||
|
||||
Times? mooringTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.MOORING);
|
||||
Times? mooringTimes = this.ShipcallControlModel?.GetTimesForParticipantType(Extensions.ParticipantType.MOORING);
|
||||
|
||||
if (mooringTimes != null)
|
||||
{
|
||||
|
||||
this.labelMooringETAETDValue.Content = mooringTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.textBlockMooringRemarks.Text = mooringTimes.Remarks;
|
||||
this.textBlockMooringRemarks.Text = mooringTimes.Remarks.TruncateDots(50);
|
||||
this.imageMooringLocked.Visibility = (mooringTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
||||
|
||||
if(mooringTimes.Ata.HasValue)
|
||||
{
|
||||
if(!ataAdded)
|
||||
{
|
||||
if(!ataAdded)
|
||||
{
|
||||
|
||||
ataRowDefinition.Height = new GridLength(15);
|
||||
labelTimesMooringATA.Content = mooringTimes.Ata.ToString();
|
||||
labelTimesMooringATA.Content = mooringTimes.Ata.Value.ToString("dd.MM.yyyy HH:mm");
|
||||
ataAdded = true;
|
||||
}
|
||||
}
|
||||
@ -350,7 +353,7 @@ namespace BreCalClient
|
||||
if (!atdAdded)
|
||||
{
|
||||
atdRowDefinition.Height = new GridLength(15);
|
||||
labelTimesMooringATD.Content = mooringTimes.Atd.ToString();
|
||||
labelTimesMooringATD.Content = mooringTimes.Atd.Value.ToString("dd.MM.yyyy HH:mm");
|
||||
atdAdded = true;
|
||||
}
|
||||
}
|
||||
@ -367,8 +370,17 @@ namespace BreCalClient
|
||||
if (portAuthorityTimes != null)
|
||||
{
|
||||
this.labelPortAuthorityETAETDValue.Content = portAuthorityTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.textBlockPortAuthorityRemarks.Text = portAuthorityTimes.Remarks;
|
||||
this.textBlockPortAuthorityRemarks.Text = portAuthorityTimes.Remarks.TruncateDots(50);
|
||||
this.imagePortAuthorityLocked.Visibility = (portAuthorityTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
||||
if(portAuthorityTimes.LockTime.HasValue)
|
||||
{
|
||||
if(!lockTimeAdded)
|
||||
{
|
||||
lockTimeRowDefinition.Height = new GridLength(15);
|
||||
labelPortAuthorityLockTime.Content = portAuthorityTimes.LockTime.Value.ToString("dd.MM.yyyy HH:mm");
|
||||
lockTimeAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -381,7 +393,7 @@ namespace BreCalClient
|
||||
if (pilotTimes != null)
|
||||
{
|
||||
this.labelPilotETAETDValue.Content = pilotTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.textBlockPilotRemarks.Text = pilotTimes.Remarks;
|
||||
this.textBlockPilotRemarks.Text = pilotTimes.Remarks.TruncateDots(50);
|
||||
this.imagePilotLocked.Visibility = (pilotTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
@ -395,7 +407,7 @@ namespace BreCalClient
|
||||
if (tugTimes != null)
|
||||
{
|
||||
this.labelTugETAETDValue.Content = tugTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.textBlockTugRemarks.Text = tugTimes.Remarks;
|
||||
this.textBlockTugRemarks.Text = tugTimes.Remarks.TruncateDots(50);
|
||||
this.imageTugLocked.Visibility = (tugTimes.EtaBerthFixed ?? false) ? Visibility.Visible : Visibility.Hidden;
|
||||
}
|
||||
else
|
||||
@ -410,8 +422,8 @@ namespace BreCalClient
|
||||
{
|
||||
this.labelTerminalBerth.Content = this.ShipcallControlModel?.GetBerthText(terminalTimes);
|
||||
this.labelOperationsStart.Content = terminalTimes.DisplayTime(this.ShipcallControlModel?.Shipcall?.Type == ShipcallType.Arrival);
|
||||
this.textBlockTerminalRemarks.Text = terminalTimes.Remarks;
|
||||
this.textBlockTerminalBerthRemarks.Text = terminalTimes.BerthInfo;
|
||||
this.textBlockTerminalRemarks.Text = terminalTimes.Remarks.TruncateDots(40);
|
||||
this.textBlockTerminalBerthRemarks.Text = terminalTimes.BerthInfo.TruncateDots(40);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -433,7 +445,7 @@ namespace BreCalClient
|
||||
|
||||
#endregion
|
||||
|
||||
#region event handler
|
||||
#region event handler
|
||||
|
||||
private void buttonEditShipcall_Click(object? sender, RoutedEventArgs? e)
|
||||
{
|
||||
|
||||
@ -16,17 +16,7 @@ namespace BreCalClient
|
||||
public class ShipcallControlModel
|
||||
{
|
||||
|
||||
#region Enumerations
|
||||
|
||||
public enum TrafficLightMode
|
||||
{
|
||||
OFF,
|
||||
GREEN,
|
||||
YELLOW,
|
||||
RED,
|
||||
RED_YELLOW,
|
||||
ALL
|
||||
};
|
||||
#region Enumerations
|
||||
|
||||
[Flags]
|
||||
public enum StatusFlags
|
||||
@ -74,20 +64,20 @@ namespace BreCalClient
|
||||
}
|
||||
}
|
||||
|
||||
public TrafficLightMode LightMode
|
||||
public EvaluationType LightMode
|
||||
{
|
||||
get
|
||||
{
|
||||
TrafficLightMode tlm = TrafficLightMode.OFF;
|
||||
EvaluationType elm = EvaluationType.Undefined;
|
||||
|
||||
if (this.Shipcall != null)
|
||||
{
|
||||
if(this.Shipcall.Evaluation.HasValue)
|
||||
{
|
||||
tlm = (TrafficLightMode)this.Shipcall.Evaluation;
|
||||
elm = this.Shipcall.Evaluation.Value;
|
||||
}
|
||||
}
|
||||
return tlm;
|
||||
return elm;
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,6 +172,33 @@ namespace BreCalClient
|
||||
return berthText;
|
||||
}
|
||||
|
||||
public string GetETAETD()
|
||||
{
|
||||
DateTime theDate = DateTime.Now;
|
||||
if(this.Shipcall != null)
|
||||
{
|
||||
if (this.Shipcall.Type == ShipcallType.Arrival)
|
||||
theDate = this.Shipcall.Eta ?? DateTime.Now;
|
||||
else
|
||||
theDate = this.Shipcall.Etd ?? DateTime.Now;
|
||||
}
|
||||
Times? agentTimes = this.GetTimesForParticipantType(Extensions.ParticipantType.AGENCY);
|
||||
if(agentTimes != null)
|
||||
{
|
||||
if(this.Shipcall?.Type == ShipcallType.Arrival)
|
||||
{
|
||||
if (agentTimes.EtaBerth != null)
|
||||
theDate = agentTimes.EtaBerth.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (agentTimes.EtdBerth != null)
|
||||
theDate = agentTimes.EtdBerth.Value;
|
||||
}
|
||||
}
|
||||
return theDate.ToString();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// After closing the edit shipcall or edit agency dialogs, the times assignments may have changed.
|
||||
|
||||
@ -62,7 +62,7 @@ def create_app(test_config=None):
|
||||
app.register_blueprint(user.bp)
|
||||
app.register_blueprint(history.bp)
|
||||
|
||||
logging.basicConfig(filename='brecaldevel.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
|
||||
logging.basicConfig(filename='brecal.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
|
||||
local_db.initPool(os.path.dirname(app.instance_path))
|
||||
logging.info('App started')
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ def PostShipcalls():
|
||||
|
||||
try:
|
||||
content = request.get_json(force=True)
|
||||
logging.info(content)
|
||||
loadedModel = model.ShipcallSchema().load(data=content, many=False, partial=True)
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
|
||||
@ -53,12 +53,16 @@ def PutShip():
|
||||
@auth_guard() # no restriction by role
|
||||
def DeleteShip():
|
||||
|
||||
# TODO check if I am allowed to delete this thing by deriving the participant from the bearer token
|
||||
try:
|
||||
content = request.get_json(force=True)
|
||||
loadedModel = model.ShipSchema().load(data=content, many=False, partial=True, unknown=EXCLUDE)
|
||||
if 'id' in request.args:
|
||||
options = {}
|
||||
options["id"] = request.args.get("id")
|
||||
else:
|
||||
return json.dumps("no id provided"), 400
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print(ex)
|
||||
return json.dumps("bad format"), 400
|
||||
|
||||
return impl.ships.DeleteShip(loadedModel)
|
||||
return impl.ships.DeleteShip(options)
|
||||
|
||||
@ -25,13 +25,9 @@ def GetShipcalls(options):
|
||||
"FROM shipcall s " +
|
||||
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 " +
|
||||
"WHERE " +
|
||||
"(type = 1 AND " +
|
||||
"((t.id IS NOT NULL AND t.eta_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||
"(eta >= DATE(NOW() - INTERVAL %d DAY)))) OR " +
|
||||
"((type = 2 OR type = 3) AND " +
|
||||
"((t.id IS NOT NULL AND t.etd_berth >= DATE(NOW() - INTERVAL %d DAY)) OR " +
|
||||
"(etd >= DATE(NOW() - INTERVAL %d DAY)))) " +
|
||||
"ORDER BY eta") % (options["past_days"], options["past_days"], options["past_days"], options["past_days"])
|
||||
"(type = 1 AND (COALESCE(t.eta_berth, eta) >= DATE(NOW() - INTERVAL %d DAY))) OR " +
|
||||
"((type = 2 OR type = 3) AND (COALESCE(t.etd_berth, etd) >= DATE(NOW() - INTERVAL %d DAY)))" +
|
||||
"ORDER BY s.id") % (options["past_days"], options["past_days"])
|
||||
|
||||
data = commands.query(query, model=model.Shipcall.from_query_row, buffered=True)
|
||||
for shipcall in data:
|
||||
@ -84,9 +80,9 @@ def PostShipcalls(schemaModel):
|
||||
if key == "evaluation":
|
||||
continue
|
||||
if key == "evaluation_message":
|
||||
continue
|
||||
continue
|
||||
if key == "type_value":
|
||||
continue
|
||||
continue
|
||||
if key == "evaluation_value":
|
||||
continue
|
||||
if isNotFirst:
|
||||
@ -96,6 +92,7 @@ def PostShipcalls(schemaModel):
|
||||
query += ") VALUES ("
|
||||
isNotFirst = False
|
||||
for key in schemaModel.keys():
|
||||
param_key = key
|
||||
if key == "id":
|
||||
continue
|
||||
if key == "participants":
|
||||
@ -119,9 +116,10 @@ def PostShipcalls(schemaModel):
|
||||
if isNotFirst:
|
||||
query += ","
|
||||
isNotFirst = True
|
||||
query += "?" + key + "?"
|
||||
query += "?" + param_key + "?"
|
||||
query += ")"
|
||||
|
||||
logging.info(query)
|
||||
commands.execute(query, schemaModel)
|
||||
new_id = commands.execute_scalar("select last_insert_id()")
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ def initPool(instancePath):
|
||||
try:
|
||||
global config_path
|
||||
if(config_path == None):
|
||||
config_path = os.path.join(instancePath,'../../../secure/connection_data_devel.json');
|
||||
config_path = os.path.join(instancePath,'../../../secure/connection_data_prod.json');
|
||||
|
||||
print (config_path)
|
||||
|
||||
@ -39,4 +39,4 @@ def getPoolConnection():
|
||||
global config_path
|
||||
f = open(config_path);
|
||||
connection_data = json.load(f)
|
||||
return mysql.connector.connect(**connection_data)
|
||||
return mysql.connector.connect(**connection_data)
|
||||
|
||||
@ -45,10 +45,17 @@ class EvaluationType(IntEnum):
|
||||
yellow = 2
|
||||
red = 3
|
||||
|
||||
@classmethod
|
||||
def _missing_(cls, value):
|
||||
return cls.undefined
|
||||
|
||||
class NotificationType(IntEnum):
|
||||
undefined = 0
|
||||
email = 1
|
||||
push = 2
|
||||
@classmethod
|
||||
def _missing_(cls, value):
|
||||
return cls.undefined
|
||||
|
||||
class ShipcallType(IntEnum):
|
||||
undefined = 0
|
||||
@ -56,6 +63,10 @@ class ShipcallType(IntEnum):
|
||||
departure = 2
|
||||
shifting = 3
|
||||
|
||||
@classmethod
|
||||
def _missing_(cls, value):
|
||||
return cls.undefined
|
||||
|
||||
|
||||
@dataclass
|
||||
class History:
|
||||
@ -183,9 +194,13 @@ class ShipcallSchema(Schema):
|
||||
|
||||
@post_load
|
||||
def make_shipcall(self, data, **kwargs):
|
||||
data['type_value'] = data['type'].value
|
||||
if 'type' in data:
|
||||
data['type_value'] = data['type'].value
|
||||
else:
|
||||
data['type_value'] = ShipcallType.undefined
|
||||
if 'evaluation' in data:
|
||||
data['evaluation_value'] = data['evaluation'].value
|
||||
if data['evaluation']:
|
||||
data['evaluation_value'] = data['evaluation'].value
|
||||
else:
|
||||
data['evaluation_value'] = EvaluationType.undefined
|
||||
return data
|
||||
|
||||
@ -25,11 +25,15 @@ def UpdateShipcalls(options:dict = {'past_days':2}):
|
||||
try:
|
||||
pooledConnection = getPoolConnection()
|
||||
commands = pydapper.using(pooledConnection)
|
||||
query = ("SELECT id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, "
|
||||
"flags, pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, "
|
||||
"anchored, moored_lock, canceled, evaluation, evaluation_message, evaluation_notifications_sent, evaluation_time, created, modified FROM shipcall WHERE ((type = 1 OR type = 3) AND eta >= DATE(NOW() - INTERVAL %d DAY)"
|
||||
"OR (type = 2 AND etd >= DATE(NOW() - INTERVAL %d DAY))) "
|
||||
"ORDER BY eta") % (options["past_days"], options["past_days"])
|
||||
|
||||
query = ("SELECT s.id as id, ship_id, type, eta, voyage, etd, arrival_berth_id, departure_berth_id, tug_required, pilot_required, "
|
||||
"flags, s.pier_side, bunkering, replenishing_terminal, replenishing_lock, draft, tidal_window_from, tidal_window_to, rain_sensitive_cargo, recommended_tugs, "
|
||||
"anchored, moored_lock, canceled, evaluation, evaluation_message, evaluation_notifications_sent, evaluation_time, s.created as created, s.modified as modified, time_ref_point FROM shipcall s " +
|
||||
"LEFT JOIN times t ON t.shipcall_id = s.id AND t.participant_type = 8 "
|
||||
"WHERE "
|
||||
"(type = 1 AND (COALESCE(t.eta_berth, eta) >= DATE(NOW() - INTERVAL %d DAY))) OR "
|
||||
"((type = 2 OR type = 3) AND (COALESCE(t.etd_berth, etd) >= DATE(NOW() - INTERVAL %d DAY)))"
|
||||
"ORDER BY s.id") % (options["past_days"], options["past_days"])
|
||||
|
||||
# obtain data from the MYSQL database
|
||||
data = commands.query(query, model=model.Shipcall)
|
||||
@ -54,6 +58,9 @@ def add_function_to_schedule__update_shipcalls(interval_in_minutes:int, options:
|
||||
return
|
||||
|
||||
def setup_schedule(update_shipcalls_interval_in_minutes:int=60):
|
||||
|
||||
logging.getLogger('schedule').setLevel(logging.INFO); # set the logging level of the schedule module to INFO
|
||||
|
||||
schedule.clear() # clear all routine jobs. This prevents jobs from being created multiple times
|
||||
|
||||
# update the evaluation state in every recent shipcall
|
||||
|
||||
@ -57,6 +57,7 @@ class ValidationRuleBaseFunctions():
|
||||
self.error_message_dict = error_message_dict
|
||||
# as of 23 dec. 2023 port authority validation is temporarily disabled
|
||||
self.ignore_port_administration_flag = True # flag to disable all port administration validation rules
|
||||
self.ignore_terminal_flag = True # flag to disable Terminal validation rules 0001-L & 0001-M
|
||||
|
||||
def describe_error_message(self, key)->str:
|
||||
"""
|
||||
@ -106,7 +107,7 @@ class ValidationRuleBaseFunctions():
|
||||
violation_state = (delta<=threshold)
|
||||
return violation_state
|
||||
|
||||
def check_participants_agree_on_estimated_time(self, shipcall, query, df_times, applicable_shipcall_type)->bool:
|
||||
def check_participants_agree_on_estimated_time(self, shipcall, query, df_times, applicable_shipcall_type, threshold:int=3660)->bool:
|
||||
"""
|
||||
# base function for all validation rules in the group {0002} A-C
|
||||
|
||||
@ -117,10 +118,12 @@ class ValidationRuleBaseFunctions():
|
||||
- the shipcall belongs to a different type than the rule expects
|
||||
- there are no matching times for the provided {query} (e.g., "eta_berth")
|
||||
|
||||
Instead of comparing each individual result, this function counts the amount of unique instances.
|
||||
When there is not only one unique value, there are deviating time estimates, and a violation occurs
|
||||
This method computes the absolute time difference between all time entries. A threshold (in seconds) is used
|
||||
to identify, when the time differences are so large, that participants essentially disagree on the times.
|
||||
This circumvents previous instabilities, which stem from rounding the pd.Timestamp elements.
|
||||
|
||||
To reduce the potential of false violations, the agreement is rounded (e.g., by minute).
|
||||
options:
|
||||
threshold: integer. Determines the threshold in seconds, when two Timestamps differ 'too much'
|
||||
|
||||
returns: violation_state (bool)
|
||||
"""
|
||||
@ -136,14 +139,14 @@ class ValidationRuleBaseFunctions():
|
||||
participant_types = [ParticipantType.AGENCY.value, ParticipantType.MOORING.value, ParticipantType.PILOT.value, ParticipantType.TUG.value]
|
||||
|
||||
agency_times = df_times.loc[df_times["participant_type"]==ParticipantType.AGENCY.value,:]
|
||||
df_times = df_times.loc[df_times["participant_type"].isin(participant_types),:]
|
||||
|
||||
|
||||
agency_time = [time_ for time_ in agency_times.loc[:,query].tolist() if isinstance(time_, pd.Timestamp)]
|
||||
if not len(agency_time):
|
||||
if len(agency_times)==0:
|
||||
violation_state = False
|
||||
return violation_state
|
||||
|
||||
df_times = df_times.loc[df_times["participant_type"].isin(participant_types),:]
|
||||
agency_time = [time_ for time_ in agency_times.loc[:,query].tolist() if isinstance(time_, pd.Timestamp)]
|
||||
|
||||
# for the given query, e.g., 'eta_berth', sample all times from the pandas DataFrame
|
||||
# exclude missing entries and consider only pd.Timestamp entries (which ignores pd.NaT/null entries)
|
||||
estimated_times = [time_ for time_ in df_times.loc[:,query].tolist() if isinstance(time_, pd.Timestamp)] # df_times = df_times.loc[~df_times[query].isnull(),:]
|
||||
|
||||
@ -151,9 +154,25 @@ class ValidationRuleBaseFunctions():
|
||||
if len(estimated_times)==0:
|
||||
violation_state = False
|
||||
return violation_state
|
||||
|
||||
# this (current) solution compares times to the reference (agency) time and checks if the difference is greater than 15 minutes
|
||||
violation_state = ((np.max(estimated_times) - agency_time[0]) > pd.Timedelta("15min")) or ((agency_time[0] - np.min(estimated_times)) > pd.Timedelta("15min"))
|
||||
|
||||
# for the given query, e.g., 'eta_berth', sample all times from the pandas DataFrame
|
||||
estimated_times = [time_ for time_ in df_times.loc[:,query].tolist() if isinstance(time_, pd.Timestamp)] # consider only pandas Timestamp objects
|
||||
|
||||
# measure the time difference between all pairs.
|
||||
# for each pair of times, the absolute timedifference in seconds (float) is measured
|
||||
time_absolute_differences = [[abs(time_.to_pydatetime()-time__.to_pydatetime()).total_seconds() for j_, time__ in enumerate(estimated_times) if j_ != i_] for i_, time_ in enumerate(estimated_times)]
|
||||
|
||||
# list of lists: for each element in the list, create a boolean that indicates, whether the threshold is exceeded
|
||||
time_difference_exceeds_threshold = [[time__ > threshold for time__ in time_] for time_ in time_absolute_differences]
|
||||
|
||||
# list of booleans for each time entry separately
|
||||
time_difference_exceeds_threshold = [any(time_) for time_ in time_difference_exceeds_threshold]
|
||||
|
||||
# if *any* of these entries exceeds the threshold, the times are too distinct. In those case, a rule violation occurs
|
||||
violation_state = any(time_difference_exceeds_threshold)
|
||||
|
||||
# this (previous) solution compares times to the reference (agency) time and checks if the difference is greater than 15 minutes
|
||||
# violation_state = ((np.max(estimated_times) - agency_time[0]) > pd.Timedelta("15min")) or ((agency_time[0] - np.min(estimated_times)) > pd.Timedelta("15min"))
|
||||
|
||||
# this solution to the rule compares all times to each other. When there is a total difference of more than 15 minutes, a violation occurs
|
||||
# Consequently, it treats all times as equally important
|
||||
@ -161,7 +180,7 @@ class ValidationRuleBaseFunctions():
|
||||
# violation_state = difference > pd.Timedelta("15min")
|
||||
|
||||
# this solution clamps the times to 15 minute intervals and compares these values. When there is a single time difference, a violation occurs
|
||||
# the drawback is that in some cases if there is a minimal difference say of 1 minute (:22 and :23 minutes after the hour) the violation is
|
||||
# the drawback is that in some cases if there is a minimal difference say of 1 minute (:22 and :23 minutes after the hour) the violation is
|
||||
# triggered even though the times are very close to each other
|
||||
|
||||
# apply rounding. For example, the agreement of different participants may be required to match minute-wise
|
||||
@ -581,6 +600,9 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
||||
- Checks, if times_terminal.operations_start is filled in.
|
||||
- Measures the difference between 'now' and 'times_agency.eta_berth'.
|
||||
"""
|
||||
if self.ignore_terminal_flag: # this feature flag may disable the validation rule for Terminals
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
if not shipcall.type in [ShipcallType.INCOMING.value]:
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
@ -615,6 +637,9 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
||||
- Checks, if times_terminal.operations_end is filled in.
|
||||
- Measures the difference between 'now' and 'times_agency.etd_berth'.
|
||||
"""
|
||||
if self.ignore_terminal_flag: # this feature flag may disable the validation rule for Terminals
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
if not shipcall.type in [ShipcallType.OUTGOING.value, ShipcallType.SHIFTING.value]:
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
@ -730,6 +755,9 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
||||
query time: eta_berth (times_agency)
|
||||
start_time & end_time: operations_start & operations_end (times_terminal)
|
||||
"""
|
||||
if self.ignore_terminal_flag: # this feature flag may disable the validation rule for Terminals
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
if not shipcall.type in [ShipcallType.INCOMING.value]:
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
@ -770,6 +798,9 @@ class ValidationRuleFunctions(ValidationRuleBaseFunctions):
|
||||
query time: eta_berth (times_agency)
|
||||
start_time & end_time: operations_start & operations_end (times_terminal)
|
||||
"""
|
||||
if self.ignore_terminal_flag: # this feature flag may disable the validation rule for Terminals
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
if not shipcall.type in [ShipcallType.OUTGOING.value, ShipcallType.SHIFTING.value]:
|
||||
return self.get_no_violation_default_output()
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import copy
|
||||
import logging
|
||||
import re
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
@ -21,7 +22,7 @@ class ValidationRules(ValidationRuleFunctions):
|
||||
# currently flagged: notification_state initially was based on using one ValidationRules object for each query. This is deprecated.
|
||||
# self.notification_state = self.determine_notification_state() # (state:str, should_notify:bool)
|
||||
return
|
||||
|
||||
|
||||
def evaluate(self, shipcall):
|
||||
"""
|
||||
1.) prepare df_times, which every validation rule tends to use
|
||||
@ -34,7 +35,7 @@ class ValidationRules(ValidationRuleFunctions):
|
||||
|
||||
if len(df_times)==0:
|
||||
return (StatusFlags.GREEN.value, [])
|
||||
|
||||
|
||||
spm = self.sql_handler.df_dict["shipcall_participant_map"]
|
||||
if len(spm.loc[spm["shipcall_id"]==shipcall.id])==0:
|
||||
return (StatusFlags.GREEN.value, [])
|
||||
@ -51,12 +52,14 @@ class ValidationRules(ValidationRuleFunctions):
|
||||
|
||||
# 'translate' all error codes into readable, human-understandable format.
|
||||
evaluation_results = [(state, self.describe_error_message(msg)) for (state, msg) in evaluation_results]
|
||||
|
||||
|
||||
logging.info(f"Validation results for shipcall {shipcall.id}: {evaluation_results}")
|
||||
|
||||
# check, what the maximum state flag is and return it
|
||||
evaluation_state = np.max(np.array([result[0].value for result in evaluation_results])) if len(evaluation_results)>0 else StatusFlags.GREEN.value
|
||||
evaluation_verbosity = [result[1] for result in evaluation_results]
|
||||
return (evaluation_state, evaluation_verbosity)
|
||||
|
||||
|
||||
def evaluation_verbosity(self, evaluation_state, evaluation_results):
|
||||
"""This function suggestions verbosity for the evaluation results. Based on 'True'/'False' evaluation outcome, the returned string is different."""
|
||||
if evaluation_state:
|
||||
@ -64,17 +67,17 @@ class ValidationRules(ValidationRuleFunctions):
|
||||
else:
|
||||
verbose_string = "These are:" + "\n\t".join(evaluation_results) # every element of the list will be displayed in a new line with a tab
|
||||
return f"FAILED VALIDATION. There have been {len(evaluation_results)} violations. {verbose_string}"
|
||||
|
||||
|
||||
def evaluate_shipcall_from_df(self, x):
|
||||
shipcall = Shipcall(**{**{'id':x.name}, **x.to_dict()})
|
||||
evaluation_state, violations = self.evaluate(shipcall)
|
||||
return evaluation_state, violations
|
||||
|
||||
|
||||
def evaluate_shipcalls(self, shipcall_df:pd.DataFrame)->pd.DataFrame:
|
||||
"""apply 'evaluate_shipcall_from_df' to each individual shipcall in {shipcall_df}. Returns shipcall_df ('evaluation' and 'evaluation_message' are updated)"""
|
||||
results = shipcall_df.apply(lambda x: self.evaluate_shipcall_from_df(x), axis=1).values
|
||||
|
||||
# unbundle individual results. evaluation_state becomes an integer, violation
|
||||
# unbundle individual results. evaluation_state becomes an integer, violation
|
||||
evaluation_state = [StatusFlags(res[0]).value for res in results]
|
||||
violations = [",\r\n".join(res[1]) if len(res[1])>0 else None for res in results]
|
||||
violations = [self.concise_evaluation_message_if_too_long(violation) for violation in violations]
|
||||
@ -90,31 +93,31 @@ class ValidationRules(ValidationRuleFunctions):
|
||||
"""
|
||||
if violation is None:
|
||||
return violation
|
||||
|
||||
|
||||
if len(violation)>=512:
|
||||
concise = re.findall(r'{(.*?)\}', violation)
|
||||
|
||||
# e.g.: Evaluation message too long. Violated Rules: ['Rule #0001C', 'Rule #0001H', 'Rule #0001F', 'Rule #0001G', 'Rule #0001L', 'Rule #0001M', 'Rule #0001J', 'Rule #0001K']
|
||||
violation = f"Evaluation message too long. Violated Rules: {concise}"
|
||||
return violation
|
||||
|
||||
|
||||
def determine_validation_state(self) -> str:
|
||||
"""
|
||||
this method determines the validation state of a shipcall. The state is either ['green', 'yellow', 'red'] and signals,
|
||||
whether an entry causes issues within the workflow of users.
|
||||
|
||||
whether an entry causes issues within the workflow of users.
|
||||
|
||||
returns: validation_state_new (str)
|
||||
"""
|
||||
(validation_state_new, description) = self.undefined_method()
|
||||
# should there also be notifications for critical validation states? In principle, the traffic light itself provides that notification.
|
||||
# should there also be notifications for critical validation states? In principle, the traffic light itself provides that notification.
|
||||
self.validation_state = validation_state_new
|
||||
return validation_state_new
|
||||
|
||||
|
||||
def determine_notification_state(self) -> (str, bool):
|
||||
"""
|
||||
this method determines state changes in the notification state. When the state is changed to yellow or red,
|
||||
a user is notified about it. The only exception for this rule is when the state was yellow or red before,
|
||||
as the user has then already been notified.
|
||||
as the user has then already been notified.
|
||||
|
||||
returns: notification_state_new (str), should_notify (bool)
|
||||
"""
|
||||
@ -122,10 +125,10 @@ class ValidationRules(ValidationRuleFunctions):
|
||||
should_notify = self.identify_notification_state_change(state_new)
|
||||
self.notification_state = state_new # overwrite the predecessor
|
||||
return state_new, should_notify
|
||||
|
||||
|
||||
def identify_notification_state_change(self, state_new) -> bool:
|
||||
"""
|
||||
determines, whether the observed state change should trigger a notification.
|
||||
determines, whether the observed state change should trigger a notification.
|
||||
internally, this function maps a color string to an integer and determines, if the successor state is more severe than the predecessor.
|
||||
|
||||
state changes trigger a notification in the following cases:
|
||||
@ -135,14 +138,14 @@ class ValidationRules(ValidationRuleFunctions):
|
||||
|
||||
(none -> yellow) or (none -> red)
|
||||
due to the values in the enumeration objects, the states are mapped to provide this function.
|
||||
green=1, yellow=2, red=3, none=1. Hence, critical changes can be observed by simply checking with "greater than".
|
||||
green=1, yellow=2, red=3, none=1. Hence, critical changes can be observed by simply checking with "greater than".
|
||||
|
||||
returns bool, whether a notification should be triggered
|
||||
"""
|
||||
# state_old is always considered at least 'Green' (1)
|
||||
state_old = max(copy.copy(self.notification_state) if "notification_state" in list(self.__dict__.keys()) else StatusFlags.NONE, StatusFlags.GREEN.value)
|
||||
return state_new.value > state_old.value
|
||||
|
||||
|
||||
def undefined_method(self) -> str:
|
||||
"""this function should apply the ValidationRules to the respective .shipcall, in regards to .times"""
|
||||
# #TODO_traffic_state
|
||||
|
||||
@ -2,7 +2,7 @@ import os
|
||||
import sys
|
||||
import logging
|
||||
|
||||
sys.path.insert(0, '/var/www/brecal_devel/src/server')
|
||||
sys.path.insert(0, '/var/www/brecal/src/server')
|
||||
sys.path.insert(0, '/var/www/venv/lib/python3.10/site-packages/')
|
||||
|
||||
import schedule
|
||||
|
||||
Loading…
Reference in New Issue
Block a user