This commit is contained in:
Meik
2025-11-11 11:03:42 +01:00
commit dc3e8a2e4c
582 changed files with 191465 additions and 0 deletions

View File

@@ -0,0 +1,228 @@
<Window x:Class="FasdDesktopUi.Pages.TicketCompletion.TicketCompletion"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FasdDesktopUi.Pages.CustomMessageBox"
xmlns:uc="clr-namespace:FasdDesktopUi.Basics.UserControls"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
xmlns:vc="clr-namespace:FasdDesktopUi.Basics.Converter"
mc:Ignorable="d"
x:Name="TicketCompletionView"
AllowsTransparency="True"
WindowStyle="None"
ResizeMode="NoResize"
SizeToContent="Height"
MaxWidth="475"
Background="Transparent"
WindowStartupLocation="CenterOwner"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
PreviewKeyDown="CustomMessageBox_PreviewKeyDown"
IsVisibleChanged="BlurInvoker_IsActiveChanged">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="40" />
</WindowChrome.WindowChrome>
<Window.Resources>
<BlurEffect x:Key="BlurEffecStyle"
Radius="4"
KernelType="Gaussian" />
<Style x:Key="BlurablePanel"
TargetType="Panel">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TicketCompletionView, Path=WaitForClosing}"
Value="True">
<Setter Property="Effect"
Value="{StaticResource BlurEffecStyle}" />
</DataTrigger>
</Style.Triggers>
</Style>
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
<vc:NullValueToVisibilityConverter x:Key="NullToVisibility" />
<vc:BoolOrToVisibilityConverter x:Key="BoolOrToVisibilityConverter" />
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
</Window.Resources>
<Border Background="{DynamicResource BackgroundColor.Menu.Categories}"
CornerRadius="7.5"
Padding="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Canvas Grid.RowSpan="999"
Panel.ZIndex="5"
Margin="-10 -10">
<Border x:Name="FocusBorder"
Background="{DynamicResource Color.BlurBorder}"
Grid.RowSpan="999"
Opacity="0.4"
Visibility="Collapsed"
Panel.ZIndex="-1"
Width="{Binding ElementName=TicketCompletionView, Path=ActualWidth}"
Height="{Binding ElementName=TicketCompletionView, Path=ActualHeight}" />
<Decorator x:Name="FocusDecorator" />
</Canvas>
<DockPanel Grid.Row="0"
Margin="0 0 0 10"
Style="{StaticResource BlurablePanel}">
<ico:AdaptableIcon DockPanel.Dock="Right"
HorizontalAlignment="Right"
Style="{DynamicResource SettingsPage.Close.Icon}"
MouseLeftButtonUp="CloseButton_Click"
TouchDown="CloseButton_Click"
SelectedInternIcon="window_close" />
<ico:AdaptableIcon x:Name="StatusIcon"
DockPanel.Dock="Left"
SecondaryIconColor="{DynamicResource Color.AppBackground}"
HorizontalAlignment="Right"
BorderPadding="0 7.5 7.5 7.5"
SelectedInternIcon="misc_ticket">
</ico:AdaptableIcon>
<TextBlock Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Dialog.CloseCase.Title}"
TextTrimming="CharacterEllipsis"
FontSize="18"
VerticalAlignment="Center"
FontFamily="Calibri"
FontWeight="Bold"
Foreground="{DynamicResource FontColor.SlimPage.WidgetCollection.Header}" />
</DockPanel>
<StackPanel Grid.Row="1"
Style="{StaticResource BlurablePanel}">
<uc:CloseCaseDialogWithTicket x:Name="CloseCaseDialogUc" />
</StackPanel>
<Border x:Name="BlurOverlayBoarder"
x:FieldModifier="private"
Grid.RowSpan="2"
Background="{DynamicResource Color.BlurBorder}"
CornerRadius="7.5"
Opacity="0.4"
Visibility="{Binding ElementName=TicketCompletionView, Path=WaitForClosing, Converter={StaticResource BoolToVisibility}}" />
<Grid x:Name="GridPanel"
Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.Row="2"
Grid.Column="0"
Margin="40 10 0 0"
Padding="10 0 10 0"
HorizontalAlignment="Right"
Height="Auto">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="{DynamicResource BackgroundColor.Menu.MainCategory}" />
<Setter Property="CornerRadius"
Value="5" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock x:Name="SafeText"
Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Dialog.CloseCase.Safe}"
Grid.Column="0"
Padding="10 10 10 10"
FontWeight="Bold"
Cursor="Hand"
MouseLeftButtonUp="SafeText_Click"
TouchDown="SafeText_Click">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Foreground"
Value="{DynamicResource Color.Green}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="False">
<Setter Property="Foreground"
Value="{DynamicResource FontColor.Menu.Categories}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Border>
<Border Grid.Row="2"
Grid.Column="1"
Margin="170 10 0 0"
Padding="10 0 10 0"
HorizontalAlignment="Right"
Height="Auto">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="{DynamicResource BackgroundColor.Menu.MainCategory}" />
<Setter Property="CornerRadius"
Value="5" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock x:Name="AbortText"
Grid.Column="1"
Padding="10 10 10 10"
Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Dialog.CloseCase.Abort}"
FontWeight="Bold"
Cursor="Hand"
MouseLeftButtonUp="AbortText_Click"
TouchDown="AbortText_Click">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Foreground"
Value="{DynamicResource Color.Red}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="False">
<Setter Property="Foreground"
Value="{DynamicResource FontColor.Menu.Categories}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Border>
<ico:AdaptableIcon Grid.ColumnSpan="999"
BorderPadding="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
IconHeight="20"
IconWidth="20"
SelectedInternGif="loadingSpinner"
Margin="50 10 0 0"
Visibility="{Binding Path=IsClosingBusy, Converter={StaticResource BoolToVisibility}}" />
</Grid>
</Grid>
</Border>
</Window>

View File

@@ -0,0 +1,278 @@
using C4IT.FASD.Base;
using FasdDesktopUi.Basics;
using FasdDesktopUi.Basics.Models;
using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Pages.TicketCompletion
{
public partial class TicketCompletion : Window, IBlurInvoker, INotifyPropertyChanged
{
private bool isCanceled = false;
private bool _WaitForClosing = false;
public bool WaitForClosing
{
get { return _WaitForClosing; }
set
{
if (value != _WaitForClosing)
{
_WaitForClosing = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("WaitForClosing"));
}
}
}
private readonly cSupportCaseDataProvider _dataProvider;
public event PropertyChangedEventHandler PropertyChanged;
private TicketCompletion(cSupportCaseDataProvider dataProvider)
{
InitializeComponent();
_dataProvider = dataProvider;
CloseCaseDialogUc.DataProvider = _dataProvider;
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
cFocusInvoker.GotFocus += ElementGotFocus;
cFocusInvoker.LostFocus += ElementLostFocus;
}
#region ClosingBusy
public bool IsClosingBusy
{
get { return (bool)GetValue(IsClosingBusyProperty); }
set { SetValue(IsClosingBusyProperty, value); }
}
public static readonly DependencyProperty IsClosingBusyProperty =
DependencyProperty.Register("IsClosingBusy", typeof(bool), typeof(TicketCompletion), new PropertyMetadata(false));
#endregion
public static bool? Show(cSupportCaseDataProvider DataProvider, Window Owner)
{
try
{
var existingMessageBox = Application.Current.Windows.Cast<Window>().FirstOrDefault(window => window is TicketCompletion);
if (existingMessageBox != null)
{
existingMessageBox.Show();
return null;
}
TicketCompletion ticketCompletion = new TicketCompletion(DataProvider);
if (Owner != null)
ticketCompletion.Owner = Owner;
else
ticketCompletion.WindowStartupLocation = WindowStartupLocation.CenterScreen;
bool? dialogResult = null;
try
{
dialogResult = ticketCompletion.ShowDialog();
}
catch (Exception E)
{
LogException(E);
}
return ticketCompletion.isCanceled ? null : dialogResult;
}
catch (Exception E)
{
LogException(E);
}
return null;
}
#region Close_Click
private void Close_Click()
{
DialogResult = null;
isCanceled = true;
Close();
}
private void CloseButton_Click(object sender, InputEventArgs e) => Close_Click();
#endregion
#region Internal Focus Events
private void ElementGotFocus(object sender, EventArgs e)
{
try
{
FocusBorder.Visibility = Visibility.Visible;
if (!(sender is FrameworkElement senderElement))
return;
if (FocusBorder.IsVisible is false)
return;
var desiredHeight = senderElement.ActualHeight;
var desiredWidth = senderElement.ActualWidth;
FrameworkElement placeHolderElement = new FrameworkElement() { Height = desiredHeight, Width = desiredWidth, Margin = senderElement.Margin };
FocusDecorator.Height = desiredHeight + senderElement.Margin.Top + senderElement.Margin.Bottom;
FocusDecorator.Width = desiredWidth + senderElement.Margin.Left + senderElement.Margin.Right;
Point relativePoint = senderElement.TransformToAncestor(this)
.Transform(new Point(0, 0));
if (senderElement.Parent is Decorator actualParentDecorator)
actualParentDecorator.Child = placeHolderElement;
else if (senderElement.Parent is Panel actualParentPanel)
{
if (actualParentPanel is Grid)
{
Grid.SetColumn(placeHolderElement, Grid.GetColumn(senderElement));
Grid.SetRow(placeHolderElement, Grid.GetRow(senderElement));
}
actualParentPanel.Children.Insert(actualParentPanel.Children.IndexOf(senderElement), placeHolderElement);
actualParentPanel.Children.Remove(senderElement);
}
Canvas.SetLeft(FocusDecorator, relativePoint.X - (senderElement.Margin.Left));
Canvas.SetTop(FocusDecorator, relativePoint.Y - senderElement.Margin.Top);
FocusDecorator.Child = senderElement;
}
catch (Exception E)
{
LogException(E);
}
}
private void ElementLostFocus(object sender, EventArgs e)
{
try
{
FocusBorder.Visibility = Visibility.Collapsed;
}
catch (Exception E)
{
LogException(E);
}
}
#endregion
private void CustomMessageBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Escape:
Close_Click();
break;
}
}
private async Task DoCloseActionAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
WaitForClosing = true;
SafeText.IsEnabled = false;
AbortText.IsEnabled = false;
IsClosingBusy = true;
bool closedSuccessfull = await CloseCaseDialogUc.CloseCaseAsync(_dataProvider.Identities.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.User).Id);
if (closedSuccessfull)
{
SuccessPage.SuccessPage successPage = new SuccessPage.SuccessPage();
successPage.Show();
await _dataProvider?.CloseCaseAsync();
DialogResult = true;
Close();
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
WaitForClosing = false;
SafeText.IsEnabled = true;
AbortText.IsEnabled = true;
LogMethodEnd(CM);
}
}
public void BlurInvoker_IsActiveChanged(object sender, DependencyPropertyChangedEventArgs e)
{
BlurInvoker.InvokeVisibilityChanged(this, new EventArgs());
}
public bool BlurInvoker_IsActive => IsVisible;
public void SetButtonStateYes(bool Enabled, string MouseOverMessage)
{
var _h = this.Dispatcher.BeginInvoke(new Action(() =>
{
try
{
ToolTip tip = null;
if (!string.IsNullOrEmpty(MouseOverMessage))
tip = new ToolTip { Content = MouseOverMessage };
SafeText.IsEnabled = Enabled;
GridPanel.ToolTip = tip;
}
catch (Exception E)
{
LogException(E);
}
}));
}
public void SetButtonStateNo(bool Enabled, string MouseOverMessage)
{
_ = this.Dispatcher.BeginInvoke(new Action(() =>
{
try
{
ToolTip tip = null;
if (!string.IsNullOrEmpty(MouseOverMessage))
tip = new ToolTip { Content = MouseOverMessage };
AbortText.IsEnabled = Enabled;
AbortText.ToolTip = tip;
}
catch (Exception E)
{
LogException(E);
}
}));
}
private async void SafeText_Click(object sender, InputEventArgs e) => await DoCloseActionAsync();
private void AbortText_Click(object sender, InputEventArgs e) => Close_Click();
}
}