aktueller Stand

This commit is contained in:
Meik
2026-02-03 16:46:49 +01:00
parent 7192319e1e
commit 696629b5a8
5 changed files with 431 additions and 284 deletions

View File

@@ -65,9 +65,14 @@ namespace C4IT.FASD.Cockpit.Communication
public abstract Task<cF4sdStagedSearchResultRelations> GetStagedRelations(Guid id, CancellationToken token); public abstract Task<cF4sdStagedSearchResultRelations> GetStagedRelations(Guid id, CancellationToken token);
public abstract Task<List<cF4sdApiSearchResultRelation>> GetSearchResultRelations(enumF4sdSearchResultClass resultType, List<cFasdApiSearchResultEntry> searchResults); public abstract Task<List<cF4sdApiSearchResultRelation>> GetSearchResultRelations(enumF4sdSearchResultClass resultType, List<cFasdApiSearchResultEntry> searchResults);
#region Ticketübersicht
public abstract Task<List<cF4sdApiSearchResultRelation>> GetTicketOverviewRelations(string key, bool useRoleScope, int count); public abstract Task<List<cF4sdApiSearchResultRelation>> GetTicketOverviewRelations(string key, bool useRoleScope, int count);
public abstract Task<Dictionary<string, int>> GetTicketOverviewCounts(IEnumerable<string> keys, bool useRoleScope); public abstract Task<Dictionary<string, int>> GetTicketOverviewCounts(IEnumerable<string> keys, bool useRoleScope);
#endregion
public abstract Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData); public abstract Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData);
public abstract Task<cF4SDHealthCardRawData> GetHealthCardData(Guid healthCardId); public abstract Task<cF4SDHealthCardRawData> GetHealthCardData(Guid healthCardId);

View File

@@ -1096,6 +1096,9 @@ namespace C4IT.FASD.Cockpit.Communication
return output; return output;
} }
#region Ticketübersicht
public override async Task<Dictionary<string, int>> GetTicketOverviewCounts(IEnumerable<string> keys, bool useRoleScope) public override async Task<Dictionary<string, int>> GetTicketOverviewCounts(IEnumerable<string> keys, bool useRoleScope)
{ {
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();
@@ -1209,6 +1212,9 @@ namespace C4IT.FASD.Cockpit.Communication
return output; return output;
} }
#endregion
public override async Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData) public override async Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData)
{ {
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();

View File

@@ -26,11 +26,16 @@ namespace C4IT.FASD.Cockpit.Communication
private readonly List<cF4SDHealthCardJsonRawData> MockupData = new List<cF4SDHealthCardJsonRawData>(); private readonly List<cF4SDHealthCardJsonRawData> MockupData = new List<cF4SDHealthCardJsonRawData>();
private readonly Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable> MockupPickup = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>(); private readonly Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable> MockupPickup = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();
#region Ticketübersicht
private readonly Dictionary<string, Dictionary<string, List<TicketOverviewRelationDefinition>>> TicketOverviewRelations = private readonly Dictionary<string, Dictionary<string, List<TicketOverviewRelationDefinition>>> TicketOverviewRelations =
new Dictionary<string, Dictionary<string, List<TicketOverviewRelationDefinition>>>(StringComparer.OrdinalIgnoreCase); new Dictionary<string, Dictionary<string, List<TicketOverviewRelationDefinition>>>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<Guid> _generatedTicketIds = new HashSet<Guid>(); private readonly HashSet<Guid> _generatedTicketIds = new HashSet<Guid>();
private readonly object _demoTicketSync = new object(); private readonly object _demoTicketSync = new object();
private const string DemoTicketHasDetailsInfoKey = "Demo.HasTicketDetails"; private const string DemoTicketHasDetailsInfoKey = "Demo.HasTicketDetails";
#endregion
public cFasdCockpitCommunicationDemo() public cFasdCockpitCommunicationDemo()
{ {
if (LoadMockupData(out var loadedData)) if (LoadMockupData(out var loadedData))
@@ -93,6 +98,9 @@ namespace C4IT.FASD.Cockpit.Communication
return null; return null;
} }
#region Ticketübersicht
private void LoadTicketOverviewRelations() private void LoadTicketOverviewRelations()
{ {
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();
@@ -394,6 +402,9 @@ namespace C4IT.FASD.Cockpit.Communication
int delay = Math.Max(240, Math.Min(baseMs + capped * perItem, 2000)); int delay = Math.Max(240, Math.Min(baseMs + capped * perItem, 2000));
return Task.Delay(delay); return Task.Delay(delay);
} }
#endregion
private bool LoadMockupData(out List<cF4SDHealthCardJsonRawData> sampleData) private bool LoadMockupData(out List<cF4SDHealthCardJsonRawData> sampleData)
{ {
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();

View File

@@ -39,9 +39,13 @@ namespace FasdDesktopUi
public System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon() { Text = $"First Aid Service Desk" }; public System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon() { Text = $"First Aid Service Desk" };
public bool UseOsLanguage = string.IsNullOrEmpty(cFasdCockpitConfig.Instance.SelectedLanguage); public bool UseOsLanguage = string.IsNullOrEmpty(cFasdCockpitConfig.Instance.SelectedLanguage);
#region Ticketübersicht
private TrayTicketNotificationManager _ticketTrayNotification; private TrayTicketNotificationManager _ticketTrayNotification;
private TileScope? _pendingTicketOverviewScope; private TileScope? _pendingTicketOverviewScope;
#endregion
private async void Application_Startup(object sender, StartupEventArgs e) private async void Application_Startup(object sender, StartupEventArgs e)
{ {
var CM = MethodBase.GetCurrentMethod(); var CM = MethodBase.GetCurrentMethod();
@@ -181,18 +185,8 @@ namespace FasdDesktopUi
if (searchView == null) if (searchView == null)
return; return;
var hasNotification = HasPendingTicketOverviewNotification(); if (TryHandleTicketOverviewNotificationClick(searchView))
if (hasNotification)
{
if (!searchView.IsVisible)
searchView.ActivateSearchView();
else
searchView.BringToFrontPreserveState();
searchView.ShowTicketOverviewPaneForScope(PendingTicketOverviewScope);
ClearTicketOverviewTrayNotification();
return; return;
}
#if isDemo #if isDemo
if (searchView.IsVisible) if (searchView.IsVisible)
@@ -281,6 +275,26 @@ namespace FasdDesktopUi
} }
} }
#region Ticketübersicht
private bool TryHandleTicketOverviewNotificationClick(SearchPageView searchView)
{
if (searchView == null)
return false;
if (!HasPendingTicketOverviewNotification())
return false;
if (!searchView.IsVisible)
searchView.ActivateSearchView();
else
searchView.BringToFrontPreserveState();
searchView.ShowTicketOverviewPaneForScope(PendingTicketOverviewScope);
ClearTicketOverviewTrayNotification();
return true;
}
private void NotifyIcon_BalloonTipClicked(object sender, EventArgs e) private void NotifyIcon_BalloonTipClicked(object sender, EventArgs e)
{ {
try try
@@ -332,6 +346,8 @@ namespace FasdDesktopUi
public TileScope? PendingTicketOverviewScope => _pendingTicketOverviewScope; public TileScope? PendingTicketOverviewScope => _pendingTicketOverviewScope;
#endregion
private System.Windows.Forms.ToolStripItem SetUpNotifyIconLanguageOption() private System.Windows.Forms.ToolStripItem SetUpNotifyIconLanguageOption()
{ {
try try

View File

@@ -36,9 +36,26 @@ namespace FasdDesktopUi.Pages.SearchPage
private static SearchPageView _instance = null; private static SearchPageView _instance = null;
private const int WM_NCHITTEST = 0x0084; private const int WM_NCHITTEST = 0x0084;
private const int HTTRANSPARENT = -1; private const int HTTRANSPARENT = -1;
#region Ticketübersicht
private readonly HashSet<TileScope> _ticketOverviewNotificationScopesPrimed = new HashSet<TileScope>(); private readonly HashSet<TileScope> _ticketOverviewNotificationScopesPrimed = new HashSet<TileScope>();
private bool _ticketOverviewFirstEventHandled; private bool _ticketOverviewFirstEventHandled;
private readonly HashSet<TileScope> _ticketOverviewInitWasEmptyScopes = new HashSet<TileScope>(); private readonly HashSet<TileScope> _ticketOverviewInitWasEmptyScopes = new HashSet<TileScope>();
private bool _ticketOverviewAutoContinueActive;
private DispatcherTimer _ticketOverviewAutoContinueFallbackTimer;
private EventHandler _ticketOverviewAutoContinueCaseChangedHandler;
private bool _renderTicketOverviewUserNames = false;
private readonly HashSet<cSearchHistorySearchResultEntry> _ticketOverviewHistoryEntries = new HashSet<cSearchHistorySearchResultEntry>();
private const string DemoTicketHasDetailsInfoKey = "Demo.HasTicketDetails";
// Event zum auslösen wenn Toggle geändert wird
public event EventHandler<bool> FilterToggleCheckedChanged;
// Aktueller Zustand der Checkbox
public bool IsFilterChecked => FilterCheckbox.IsChecked == true;
#endregion
public static SearchPageView Instance public static SearchPageView Instance
{ {
get get
@@ -55,14 +72,6 @@ namespace FasdDesktopUi.Pages.SearchPage
private bool _isActivating = false; private bool _isActivating = false;
private cF4sdApiSearchResultRelation preSelectedRelation = null; private cF4sdApiSearchResultRelation preSelectedRelation = null;
private bool _renderTicketOverviewUserNames = false;
private readonly HashSet<cSearchHistorySearchResultEntry> _ticketOverviewHistoryEntries = new HashSet<cSearchHistorySearchResultEntry>();
private const string DemoTicketHasDetailsInfoKey = "Demo.HasTicketDetails";
// Event zum auslösen wenn Toggle geändert wird
public event EventHandler<bool> FilterToggleCheckedChanged;
// Aktueller Zustand der Checkbox
public bool IsFilterChecked => FilterCheckbox.IsChecked == true;
private readonly IRelationService _relationService = new RelationService(); private readonly IRelationService _relationService = new RelationService();
public SupportCaseSearchService SearchService { get; } public SupportCaseSearchService SearchService { get; }
@@ -166,112 +175,12 @@ namespace FasdDesktopUi.Pages.SearchPage
BodyStack_SearchResults.Visibility = (isVisible || SearchResultBorder.IsVisible) ? Visibility.Visible : Visibility.Collapsed; BodyStack_SearchResults.Visibility = (isVisible || SearchResultBorder.IsVisible) ? Visibility.Visible : Visibility.Collapsed;
ScheduleSearchResultMaxHeightUpdate(); ScheduleSearchResultMaxHeightUpdate();
} }
private bool CheckTicketOverviewAvailability()
{
return cFasdCockpitConfig.Instance?.Global?.TicketConfiguration?.ShowOverview == true;
}
private void UpdateTicketOverviewAvailability()
{
var enabled = CheckTicketOverviewAvailability();
var service = TicketOverviewUpdateService.Instance;
service?.UpdateAvailability(enabled);
if (enabled)
_ = service?.FetchAsync();
if (!enabled)
{
if (Dispatcher.CheckAccess())
{
ApplyTicketOverviewDisabledState();
}
else
{
Dispatcher.Invoke(ApplyTicketOverviewDisabledState);
}
}
}
private void ApplyTicketOverviewDisabledState()
{
_renderTicketOverviewUserNames = false;
_ticketOverviewNotificationScopesPrimed.Clear();
_ticketOverviewFirstEventHandled = false;
_ticketOverviewInitWasEmptyScopes.Clear();
SetTicketOverviewVisibility(false);
(Application.Current as App)?.ClearTicketOverviewTrayNotification();
}
private void SetTicketOverviewVisibility(bool isVisible)
{
var b = isVisible;
if (!CheckTicketOverviewAvailability())
b = false;
BodyStack_TicketOverview.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
TicketOverviewBorder.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
FilterCheckbox.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
RoleLabel.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
OwnTicketsLabel.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
TicketOverviewLabel.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
ScheduleSearchResultMaxHeightUpdate();
}
public void ShowLoadingTextItem(string itemText) public void ShowLoadingTextItem(string itemText)
{ {
SetSearchHistoryVisibility(false); SetSearchHistoryVisibility(false);
ResultMenu.ShowLoadingTextItem(itemText); ResultMenu.ShowLoadingTextItem(itemText);
} }
public void ShowTicketOverviewPane()
{
Dispatcher.Invoke(() =>
{
bool overviewAlreadyVisible = TicketOverviewBorder.Visibility == Visibility.Visible;
SetTicketOverviewVisibility(true);
if (!overviewAlreadyVisible)
{
SetSearchResultVisibility(false);
SetSearchHistoryVisibility(false);
TicketOverviewUc?.ResetSelection();
}
TicketOverviewUc?.RefreshHighlightState(IsFilterChecked);
var app = Application.Current as FasdDesktopUi.App;
app?.ClearTicketOverviewTrayNotification();
});
}
public void ShowTicketOverviewPaneForScope(TileScope? scope)
{
if (scope.HasValue)
{
Dispatcher.Invoke(() =>
{
if (TicketOverviewBorder.Visibility == Visibility.Visible)
return;
var useRoleScope = scope.Value == TileScope.Role;
if (FilterCheckbox != null && FilterCheckbox.IsChecked != useRoleScope)
FilterCheckbox.IsChecked = useRoleScope;
});
}
ShowTicketOverviewPane();
}
internal void CloseTicketOverviewResults()
{
_renderTicketOverviewUserNames = false;
ResultMenu.ShowSearchResults(new cFilteredResults(), null, this);
ResultMenu.SetHeaderText(string.Empty);
SetSearchResultVisibility(false);
SetTicketOverviewVisibility(true);
}
public void ShowSearchRelations(cSearchHistorySearchResultEntry searchHistoryEntry, IRelationService relationService, ISearchUiProvider searchUiProvider) public void ShowSearchRelations(cSearchHistorySearchResultEntry searchHistoryEntry, IRelationService relationService, ISearchUiProvider searchUiProvider)
{ {
try try
@@ -409,10 +318,10 @@ namespace FasdDesktopUi.Pages.SearchPage
private void ShowExternalSearchInfo(string strInfo, cFasdApiSearchResultCollection resultEntry, enumF4sdSearchResultClass Class) private void ShowExternalSearchInfo(string strInfo, cFasdApiSearchResultCollection resultEntry, enumF4sdSearchResultClass Class)
{ {
var filteredResults = new cFilteredResults(resultEntry) { AutoContinue = true }; var filteredResults = new cFilteredResults(resultEntry) { AutoContinue = true };
var _t = ShowExternalSearchInfoAsync(strInfo, filteredResults, Class); var _t = ShowExternalSearchInfoAsync(strInfo, filteredResults, Class, suppressUi: false);
} }
private async Task ShowExternalSearchInfoAsync(string strInfo, cFilteredResults result, enumF4sdSearchResultClass Class) private async Task ShowExternalSearchInfoAsync(string strInfo, cFilteredResults result, enumF4sdSearchResultClass Class, bool suppressUi)
{ {
try try
{ {
@@ -428,7 +337,11 @@ namespace FasdDesktopUi.Pages.SearchPage
ResultMenu.SelectCurrentResultItem(); ResultMenu.SelectCurrentResultItem();
} }
if (!suppressUi && !_ticketOverviewAutoContinueActive)
{
Show(); Show();
Activate();
}
} }
catch (Exception E) catch (Exception E)
{ {
@@ -903,6 +816,107 @@ namespace FasdDesktopUi.Pages.SearchPage
} }
} }
#region Ticketübersicht
private bool CheckTicketOverviewAvailability()
{
return cFasdCockpitConfig.Instance?.Global?.TicketConfiguration?.ShowOverview == true;
}
private void UpdateTicketOverviewAvailability()
{
var enabled = CheckTicketOverviewAvailability();
var service = TicketOverviewUpdateService.Instance;
service?.UpdateAvailability(enabled);
if (enabled)
_ = service?.FetchAsync();
if (!enabled)
{
if (Dispatcher.CheckAccess())
{
ApplyTicketOverviewDisabledState();
}
else
{
Dispatcher.Invoke(ApplyTicketOverviewDisabledState);
}
}
}
private void ApplyTicketOverviewDisabledState()
{
_renderTicketOverviewUserNames = false;
_ticketOverviewNotificationScopesPrimed.Clear();
_ticketOverviewFirstEventHandled = false;
_ticketOverviewInitWasEmptyScopes.Clear();
SetTicketOverviewVisibility(false);
(Application.Current as App)?.ClearTicketOverviewTrayNotification();
}
private void SetTicketOverviewVisibility(bool isVisible)
{
var b = isVisible;
if (!CheckTicketOverviewAvailability())
b = false;
BodyStack_TicketOverview.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
TicketOverviewBorder.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
FilterCheckbox.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
RoleLabel.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
OwnTicketsLabel.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
TicketOverviewLabel.Visibility = b ? Visibility.Visible : Visibility.Collapsed;
ScheduleSearchResultMaxHeightUpdate();
}
public void ShowTicketOverviewPane()
{
Dispatcher.Invoke(() =>
{
bool overviewAlreadyVisible = TicketOverviewBorder.Visibility == Visibility.Visible;
SetTicketOverviewVisibility(true);
if (!overviewAlreadyVisible)
{
SetSearchResultVisibility(false);
SetSearchHistoryVisibility(false);
TicketOverviewUc?.ResetSelection();
}
TicketOverviewUc?.RefreshHighlightState(IsFilterChecked);
var app = Application.Current as FasdDesktopUi.App;
app?.ClearTicketOverviewTrayNotification();
});
}
public void ShowTicketOverviewPaneForScope(TileScope? scope)
{
if (scope.HasValue)
{
Dispatcher.Invoke(() =>
{
if (TicketOverviewBorder.Visibility == Visibility.Visible)
return;
var useRoleScope = scope.Value == TileScope.Role;
if (FilterCheckbox != null && FilterCheckbox.IsChecked != useRoleScope)
FilterCheckbox.IsChecked = useRoleScope;
});
}
ShowTicketOverviewPane();
}
internal void CloseTicketOverviewResults()
{
_renderTicketOverviewUserNames = false;
ResultMenu.ShowSearchResults(new cFilteredResults(), null, this);
ResultMenu.SetHeaderText(string.Empty);
SetSearchResultVisibility(false);
SetTicketOverviewVisibility(true);
}
private void TicketOverviewUpdateService_OverviewCountsChanged(object sender, TicketOverviewCountsChangedEventArgs e) private void TicketOverviewUpdateService_OverviewCountsChanged(object sender, TicketOverviewCountsChangedEventArgs e)
{ {
try try
@@ -994,14 +1008,17 @@ namespace FasdDesktopUi.Pages.SearchPage
relation.Infos.TryGetValue("UserSid", out sids); relation.Infos.TryGetValue("UserSid", out sids);
} }
return RunTicketSearchAsync(ticketName, ticketId, userName, sids); return RunTicketSearchAsync(ticketName, ticketId, userName, sids, suppressUi: true);
} }
private Task RunTicketSearchAsync(string ticketName, Guid ticketId, string userName, string sids) private Task RunTicketSearchAsync(string ticketName, Guid ticketId, string userName, string sids, bool suppressUi = false)
{ {
if (ticketId == Guid.Empty) if (ticketId == Guid.Empty)
return Task.CompletedTask; return Task.CompletedTask;
if (suppressUi)
BeginTicketOverviewAutoContinue(TimeSpan.FromSeconds(6));
return Task.Run(async () => return Task.Run(async () =>
{ {
try try
@@ -1012,10 +1029,19 @@ namespace FasdDesktopUi.Pages.SearchPage
if (_result is null || _result.Count == 0 || _result.First().Value.Count == 0) if (_result is null || _result.Count == 0 || _result.First().Value.Count == 0)
{ {
LogEntry($"No corresponding user could be found for ticket '{ticketName}'", LogLevels.Warning); LogEntry($"No corresponding user could be found for ticket '{ticketName}'", LogLevels.Warning);
if (suppressUi)
EndTicketOverviewAutoContinue(showSearch: true);
return; return;
} }
var userId = _result.Values.First().First().id; var userId = _result.Values.First().First().id;
if (userId == Guid.Empty)
{
LogEntry($"No valid user id could be found for ticket '{ticketName}'", LogLevels.Warning);
if (suppressUi)
EndTicketOverviewAutoContinue(showSearch: true);
return;
}
var _ticketRelation = new cF4sdApiSearchResultRelation() var _ticketRelation = new cF4sdApiSearchResultRelation()
{ {
Type = enumF4sdSearchResultClass.Ticket, Type = enumF4sdSearchResultClass.Ticket,
@@ -1040,15 +1066,96 @@ namespace FasdDesktopUi.Pages.SearchPage
var filteredResults = new cFilteredResults(_result) { AutoContinue = true, PreSelectedRelation = _ticketRelation }; var filteredResults = new cFilteredResults(_result) { AutoContinue = true, PreSelectedRelation = _ticketRelation };
var strInfo = string.Format(cMultiLanguageSupport.GetItem("Searchbar.TicketSearch.Info"), ticketName); var strInfo = string.Format(cMultiLanguageSupport.GetItem("Searchbar.TicketSearch.Info"), ticketName);
await ShowExternalSearchInfoAsync(strInfo, filteredResults, enumF4sdSearchResultClass.Ticket); await ShowExternalSearchInfoAsync(strInfo, filteredResults, enumF4sdSearchResultClass.Ticket, suppressUi);
} }
catch (Exception E) catch (Exception E)
{ {
LogException(E); LogException(E);
if (suppressUi)
EndTicketOverviewAutoContinue(showSearch: true);
} }
}); });
} }
private void BeginTicketOverviewAutoContinue(TimeSpan fallbackTimeout)
{
if (Dispatcher.CheckAccess())
BeginTicketOverviewAutoContinueCore(fallbackTimeout);
else
Dispatcher.Invoke(() => BeginTicketOverviewAutoContinueCore(fallbackTimeout));
}
private void BeginTicketOverviewAutoContinueCore(TimeSpan fallbackTimeout)
{
if (_ticketOverviewAutoContinueActive)
return;
_ticketOverviewAutoContinueActive = true;
SearchBarUc.IsHitTestVisible = false;
ResultMenu.IsHitTestVisible = false;
SearchHistory.IsHitTestVisible = false;
BodyStack_TicketOverview.IsHitTestVisible = false;
FilterCheckbox.IsHitTestVisible = false;
SetSearchHistoryVisibility(false);
SetSearchResultVisibility(false);
_ticketOverviewAutoContinueCaseChangedHandler = (sender, args) => EndTicketOverviewAutoContinue(showSearch: false);
cSupportCaseDataProvider.CaseChanged += _ticketOverviewAutoContinueCaseChangedHandler;
_ticketOverviewAutoContinueFallbackTimer = new DispatcherTimer { Interval = fallbackTimeout };
_ticketOverviewAutoContinueFallbackTimer.Tick += TicketOverviewAutoContinueFallbackTimer_Tick;
_ticketOverviewAutoContinueFallbackTimer.Start();
}
private void TicketOverviewAutoContinueFallbackTimer_Tick(object sender, EventArgs e)
{
EndTicketOverviewAutoContinue(showSearch: true);
}
private void EndTicketOverviewAutoContinue(bool showSearch)
{
if (Dispatcher.CheckAccess())
EndTicketOverviewAutoContinueCore(showSearch);
else
Dispatcher.Invoke(() => EndTicketOverviewAutoContinueCore(showSearch));
}
private void EndTicketOverviewAutoContinueCore(bool showSearch)
{
if (!_ticketOverviewAutoContinueActive)
return;
_ticketOverviewAutoContinueActive = false;
if (_ticketOverviewAutoContinueFallbackTimer != null)
{
_ticketOverviewAutoContinueFallbackTimer.Stop();
_ticketOverviewAutoContinueFallbackTimer.Tick -= TicketOverviewAutoContinueFallbackTimer_Tick;
_ticketOverviewAutoContinueFallbackTimer = null;
}
if (_ticketOverviewAutoContinueCaseChangedHandler != null)
{
cSupportCaseDataProvider.CaseChanged -= _ticketOverviewAutoContinueCaseChangedHandler;
_ticketOverviewAutoContinueCaseChangedHandler = null;
}
SearchBarUc.IsHitTestVisible = true;
ResultMenu.IsHitTestVisible = true;
SearchHistory.IsHitTestVisible = true;
BodyStack_TicketOverview.IsHitTestVisible = true;
FilterCheckbox.IsHitTestVisible = true;
if (showSearch)
{
SetSearchResultVisibility(true);
Show();
Activate();
}
}
private void PrimeTicketOverviewScope(TileScope scope) private void PrimeTicketOverviewScope(TileScope scope)
{ {
if (_ticketOverviewNotificationScopesPrimed.Add(scope)) if (_ticketOverviewNotificationScopesPrimed.Add(scope))
@@ -1266,72 +1373,6 @@ namespace FasdDesktopUi.Pages.SearchPage
return cMultiLanguageSupport.GetItem(translationKey) ?? rowLabel; return cMultiLanguageSupport.GetItem(translationKey) ?? rowLabel;
} }
private IntPtr SearchViewWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_NCHITTEST)
{
if (!IsPointWithinInteractiveBounds(lParam))
{
handled = true;
return new IntPtr(HTTRANSPARENT);
}
}
return IntPtr.Zero;
}
private bool IsPointWithinInteractiveBounds(IntPtr lParam)
{
if (!IsLoaded || MainBorder == null || !MainBorder.IsLoaded)
return true;
if (MainBorder.ActualWidth <= 0 || MainBorder.ActualHeight <= 0)
return true;
var screenPoint = ExtractScreenPoint(lParam);
var windowPoint = PointFromScreen(screenPoint);
if (!(InputHitTest(windowPoint) is DependencyObject hitElement))
return false;
return IsDescendantOf(hitElement, MainBorder);
}
private static Point ExtractScreenPoint(IntPtr lParam)
{
int value = unchecked((int)(long)lParam);
short x = (short)(value & 0xFFFF);
short y = (short)((value >> 16) & 0xFFFF);
return new Point(x, y);
}
private static bool IsDescendantOf(DependencyObject element, DependencyObject ancestor)
{
while (element != null)
{
if (element == ancestor)
return true;
element = GetParent(element);
}
return false;
}
private static DependencyObject GetParent(DependencyObject current)
{
if (current == null)
return null;
if (current is Visual || current is System.Windows.Media.Media3D.Visual3D)
return VisualTreeHelper.GetParent(current);
if (current is System.Windows.ContentElement contentElement)
return System.Windows.ContentOperations.GetParent(contentElement);
return LogicalTreeHelper.GetParent(current);
}
private void ShowTicketOverviewNotification(string message) private void ShowTicketOverviewNotification(string message)
{ {
if (string.IsNullOrWhiteSpace(message)) if (string.IsNullOrWhiteSpace(message))
@@ -1655,6 +1696,74 @@ namespace FasdDesktopUi.Pages.SearchPage
} }
} }
#endregion
private IntPtr SearchViewWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_NCHITTEST)
{
if (!IsPointWithinInteractiveBounds(lParam))
{
handled = true;
return new IntPtr(HTTRANSPARENT);
}
}
return IntPtr.Zero;
}
private bool IsPointWithinInteractiveBounds(IntPtr lParam)
{
if (!IsLoaded || MainBorder == null || !MainBorder.IsLoaded)
return true;
if (MainBorder.ActualWidth <= 0 || MainBorder.ActualHeight <= 0)
return true;
var screenPoint = ExtractScreenPoint(lParam);
var windowPoint = PointFromScreen(screenPoint);
if (!(InputHitTest(windowPoint) is DependencyObject hitElement))
return false;
return IsDescendantOf(hitElement, MainBorder);
}
private static Point ExtractScreenPoint(IntPtr lParam)
{
int value = unchecked((int)(long)lParam);
short x = (short)(value & 0xFFFF);
short y = (short)((value >> 16) & 0xFFFF);
return new Point(x, y);
}
private static bool IsDescendantOf(DependencyObject element, DependencyObject ancestor)
{
while (element != null)
{
if (element == ancestor)
return true;
element = GetParent(element);
}
return false;
}
private static DependencyObject GetParent(DependencyObject current)
{
if (current == null)
return null;
if (current is Visual || current is System.Windows.Media.Media3D.Visual3D)
return VisualTreeHelper.GetParent(current);
if (current is System.Windows.ContentElement contentElement)
return System.Windows.ContentOperations.GetParent(contentElement);
return LogicalTreeHelper.GetParent(current);
}
private void UpdateSearchResults(cFilteredResults filteredResults) private void UpdateSearchResults(cFilteredResults filteredResults)
{ {
this.Dispatcher.Invoke(new Action(() => this.Dispatcher.Invoke(new Action(() =>