Files
C4IT-F4SD-Client/FasdDesktopUi/Basics/UserControls/InformationClassSearchBar.xaml.cs
Meik 0b52999b1d feat: expand cockpit integrations and support workflows
Add Phoenix remote desktop, action connector, documentation engine, and gamification support. Refactor support-case processing and search/action UI, and update installer assets and dependencies.
2026-07-13 11:16:53 +02:00

288 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using FasdDesktopUi.Basics.Models;
using C4IT.FASD.Cockpit.Communication;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using C4IT.MultiLanguage;
using C4IT.FASD.Base;
namespace FasdDesktopUi.Basics.UserControls
{
public partial class InformationClassSearchBar : UserControl, IBlurInvoker
{
#region Properties
public enum eSearchStatus { message, active, fixedResult }
public eSearchStatus SearchStatus { get; private set; } = eSearchStatus.message;
private static CancellationTokenSource _currentSearchTaskToken = null;
private static Guid? _currentSearchTaskId = null;
private static readonly object _currentSearchTaskLock = new object();
private readonly Dictionary<enumF4sdSearchResultClass, UIElement> _searchIcons = null;
public delegate Task ChangedSearchValueDelegate(cFilteredResults results);
public ChangedSearchValueDelegate ChangedSearchValue { get; set; } = null;
public Action CancledSearchAction { get; set; }
public bool BlurInvoker_IsActive => IsVisible;
public string SearchValue => InnerSearchBar.SearchValue;
#endregion
#region Dependency Properties
public static readonly DependencyProperty SearchButtonSizeProperty =
DependencyProperty.Register(nameof(SearchButtonSize), typeof(double), typeof(InformationClassSearchBar), new PropertyMetadata(30.0));
public double SearchButtonSize
{
get => (double)GetValue(SearchButtonSizeProperty);
set => SetValue(SearchButtonSizeProperty, value);
}
public static readonly DependencyProperty CloseButtonSizeProperty =
DependencyProperty.Register(nameof(CloseButtonSize), typeof(double), typeof(InformationClassSearchBar), new PropertyMetadata(30.0));
public double CloseButtonSize
{
get => (double)GetValue(CloseButtonSizeProperty);
set => SetValue(CloseButtonSizeProperty, value);
}
#endregion
public InformationClassSearchBar()
{
InitializeComponent();
_searchIcons = new Dictionary<enumF4sdSearchResultClass, UIElement>
{
{ enumF4sdSearchResultClass.Phone, PhoneCallIndicator },
{ enumF4sdSearchResultClass.User, UserCallIndicator },
{ enumF4sdSearchResultClass.Computer, ComputerCallIndicator }
};
}
public void BlurInvoker_IsActiveChanged(object sender, DependencyPropertyChangedEventArgs e)
{
BlurInvoker.InvokeVisibilityChanged(this, new EventArgs());
if (e.NewValue is bool newVisible)
{
if (!newVisible)
{
InnerSearchBar.IsInputEnabled = true;
InnerSearchBar.ShowSearchButton = true;
WarningIndicator.Visibility = Visibility.Collapsed;
TicketOverview.Instance?.ResetSelection();
foreach (var entry in _searchIcons.Values)
entry.Visibility = Visibility.Collapsed;
}
SetApiStatus();
}
if (Visibility == Visibility.Visible)
Dispatcher.BeginInvoke((Action)(() => InnerSearchBar.FocusInput()), DispatcherPriority.Render);
}
public void Clear()
{
SearchStatus = eSearchStatus.message;
InnerSearchBar.Clear();
}
public void ActivateManualSearch()
{
SearchStatus = eSearchStatus.active;
InnerSearchBar.ShowSearchButton = true;
WarningIndicator.Visibility = Visibility.Collapsed;
foreach (var entry in _searchIcons.Values)
entry.Visibility = Visibility.Collapsed;
InnerSearchBar.Clear();
InnerSearchBar.IsInputEnabled = true;
InnerSearchBar.FocusInput();
}
public void SetSearchText(string search)
{
SearchStatus = eSearchStatus.active;
InnerSearchBar.SetSearchText(search);
}
public void SetSpinnerVisibility(Visibility visibility)
{
InnerSearchBar.SetSpinnerVisibility(visibility);
}
public async Task SetFixedSearchResultAsync(enumF4sdSearchResultClass resultClass, string search, cFilteredResults result)
{
SearchStatus = eSearchStatus.fixedResult;
InnerSearchBar.IsInputEnabled = false;
InnerSearchBar.ShowSearchButton = false;
WarningIndicator.Visibility = Visibility.Collapsed;
foreach (var entryIcon in _searchIcons)
entryIcon.Value.Visibility = entryIcon.Key == resultClass ? Visibility.Visible : Visibility.Collapsed;
InnerSearchBar.SetSearchText(search);
if (ChangedSearchValue != null)
await ChangedSearchValue.Invoke(result);
}
public void SetApiStatus()
{
try
{
var status = cConnectionStatusHelper.Instance?.ApiConnectionStatus;
if (status == null)
return;
bool isEnabled = false;
string txt = null;
switch (status)
{
case cConnectionStatusHelper.enumOnlineStatus.online:
isEnabled = true;
break;
case cConnectionStatusHelper.enumOnlineStatus.connectionError:
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ConnectError");
break;
case cConnectionStatusHelper.enumOnlineStatus.incompatibleServerVersion:
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.IncompatibleVersion");
break;
case cConnectionStatusHelper.enumOnlineStatus.serverStarting:
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ServerStarting");
break;
case cConnectionStatusHelper.enumOnlineStatus.serverNotConfigured:
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.ServerNotConfigured");
break;
case cConnectionStatusHelper.enumOnlineStatus.illegalConfig:
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.IllegalConfig");
break;
case cConnectionStatusHelper.enumOnlineStatus.unauthorized:
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.Unauthorized");
break;
default:
txt = cMultiLanguageSupport.GetItem("Searchbar.Status.Offline");
break;
}
if (!isEnabled)
{
SearchStatus = eSearchStatus.message;
InnerSearchBar.SetSearchText(txt);
InnerSearchBar.IsInputEnabled = false;
WarningIndicator.Visibility = Visibility.Visible;
InnerSearchBar.ShowSearchButton = false;
foreach (var entry in _searchIcons.Values)
entry.Visibility = Visibility.Collapsed;
}
}
catch (Exception e)
{
LogException(e);
}
}
private async Task CancelRunningSearchTaskAsync()
{
lock (_currentSearchTaskLock)
{
if (_currentSearchTaskToken != null)
{
LogEntry("Canceling current running search...");
_currentSearchTaskToken.Cancel(true);
_currentSearchTaskToken = null;
}
}
Guid? currentTaskId = null;
lock (_currentSearchTaskLock)
{
if (_currentSearchTaskId != null)
{
currentTaskId = _currentSearchTaskId;
_currentSearchTaskId = null;
}
}
if (currentTaskId != null)
{
LogEntry("Sending a search stop...");
await cFasdCockpitCommunicationBase.Instance.GetSearchResultsStop((Guid)currentTaskId, CancellationToken.None);
}
}
private async void InnerSearchBar_SearchValueChanged(object sender, string searchValue)
{
MethodBase cm = null;
if (cLogManager.DefaultLogger.IsDebug) { cm = MethodBase.GetCurrentMethod(); LogMethodBegin(cm); }
try
{
await CancelRunningSearchTaskAsync();
lock (_currentSearchTaskLock)
{
LogEntry("Start running new search...");
SearchValueChanged?.Invoke(this, searchValue);
}
}
catch (Exception e)
{
LogException(e);
}
finally
{
if (cm != null) LogMethodEnd(cm);
}
}
private void InnerSearchBar_CancelledSearch(object sender, RoutedEventArgs e)
{
e.Handled = true;
RaiseCancledSearchEvent();
if (cConnectionStatusHelper.Instance?.ApiConnectionStatus == cConnectionStatusHelper.enumOnlineStatus.online)
InnerSearchBar.Clear();
CancledSearchAction?.Invoke();
}
#region Events
public event EventHandler<string> SearchValueChanged;
public static readonly RoutedEvent CancledSearchEvent =
EventManager.RegisterRoutedEvent(nameof(CancledSearch), RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(InformationClassSearchBar));
public event RoutedEventHandler CancledSearch
{
add => AddHandler(CancledSearchEvent, value);
remove => RemoveHandler(CancledSearchEvent, value);
}
private void RaiseCancledSearchEvent()
{
RaiseEvent(new RoutedEventArgs(CancledSearchEvent));
}
#endregion
}
}