aktueller Stand
This commit is contained in:
@@ -65,9 +65,14 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
public abstract Task<cF4sdStagedSearchResultRelations> GetStagedRelations(Guid id, CancellationToken token);
|
||||
|
||||
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<Dictionary<string, int>> GetTicketOverviewCounts(IEnumerable<string> keys, bool useRoleScope);
|
||||
|
||||
#endregion
|
||||
|
||||
public abstract Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData);
|
||||
|
||||
public abstract Task<cF4SDHealthCardRawData> GetHealthCardData(Guid healthCardId);
|
||||
|
||||
@@ -1096,6 +1096,9 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#region Ticketübersicht
|
||||
|
||||
public override async Task<Dictionary<string, int>> GetTicketOverviewCounts(IEnumerable<string> keys, bool useRoleScope)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
@@ -1209,6 +1212,9 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override async Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
|
||||
@@ -26,11 +26,16 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
private readonly List<cF4SDHealthCardJsonRawData> MockupData = new List<cF4SDHealthCardJsonRawData>();
|
||||
|
||||
private readonly Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable> MockupPickup = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTable>();
|
||||
|
||||
#region Ticketübersicht
|
||||
|
||||
private readonly Dictionary<string, Dictionary<string, List<TicketOverviewRelationDefinition>>> TicketOverviewRelations =
|
||||
new Dictionary<string, Dictionary<string, List<TicketOverviewRelationDefinition>>>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly HashSet<Guid> _generatedTicketIds = new HashSet<Guid>();
|
||||
private readonly object _demoTicketSync = new object();
|
||||
private const string DemoTicketHasDetailsInfoKey = "Demo.HasTicketDetails";
|
||||
|
||||
#endregion
|
||||
public cFasdCockpitCommunicationDemo()
|
||||
{
|
||||
if (LoadMockupData(out var loadedData))
|
||||
@@ -93,6 +98,9 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#region Ticketübersicht
|
||||
|
||||
private void LoadTicketOverviewRelations()
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
@@ -394,6 +402,9 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
int delay = Math.Max(240, Math.Min(baseMs + capped * perItem, 2000));
|
||||
return Task.Delay(delay);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private bool LoadMockupData(out List<cF4SDHealthCardJsonRawData> sampleData)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
|
||||
@@ -39,9 +39,13 @@ namespace FasdDesktopUi
|
||||
public System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon() { Text = $"First Aid Service Desk" };
|
||||
public bool UseOsLanguage = string.IsNullOrEmpty(cFasdCockpitConfig.Instance.SelectedLanguage);
|
||||
|
||||
#region Ticketübersicht
|
||||
|
||||
private TrayTicketNotificationManager _ticketTrayNotification;
|
||||
private TileScope? _pendingTicketOverviewScope;
|
||||
|
||||
#endregion
|
||||
|
||||
private async void Application_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
@@ -181,18 +185,8 @@ namespace FasdDesktopUi
|
||||
if (searchView == null)
|
||||
return;
|
||||
|
||||
var hasNotification = HasPendingTicketOverviewNotification();
|
||||
if (hasNotification)
|
||||
{
|
||||
if (!searchView.IsVisible)
|
||||
searchView.ActivateSearchView();
|
||||
else
|
||||
searchView.BringToFrontPreserveState();
|
||||
|
||||
searchView.ShowTicketOverviewPaneForScope(PendingTicketOverviewScope);
|
||||
ClearTicketOverviewTrayNotification();
|
||||
if (TryHandleTicketOverviewNotificationClick(searchView))
|
||||
return;
|
||||
}
|
||||
|
||||
#if isDemo
|
||||
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)
|
||||
{
|
||||
try
|
||||
@@ -332,6 +346,8 @@ namespace FasdDesktopUi
|
||||
|
||||
public TileScope? PendingTicketOverviewScope => _pendingTicketOverviewScope;
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolStripItem SetUpNotifyIconLanguageOption()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -36,9 +36,26 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
private static SearchPageView _instance = null;
|
||||
private const int WM_NCHITTEST = 0x0084;
|
||||
private const int HTTRANSPARENT = -1;
|
||||
|
||||
#region Ticketübersicht
|
||||
|
||||
private readonly HashSet<TileScope> _ticketOverviewNotificationScopesPrimed = new HashSet<TileScope>();
|
||||
private bool _ticketOverviewFirstEventHandled;
|
||||
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
|
||||
{
|
||||
get
|
||||
@@ -55,14 +72,6 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
private bool _isActivating = false;
|
||||
|
||||
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();
|
||||
public SupportCaseSearchService SearchService { get; }
|
||||
@@ -166,112 +175,12 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
BodyStack_SearchResults.Visibility = (isVisible || SearchResultBorder.IsVisible) ? Visibility.Visible : Visibility.Collapsed;
|
||||
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)
|
||||
{
|
||||
SetSearchHistoryVisibility(false);
|
||||
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)
|
||||
{
|
||||
try
|
||||
@@ -409,10 +318,10 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
private void ShowExternalSearchInfo(string strInfo, cFasdApiSearchResultCollection resultEntry, enumF4sdSearchResultClass Class)
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -428,7 +337,11 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
ResultMenu.SelectCurrentResultItem();
|
||||
}
|
||||
|
||||
Show();
|
||||
if (!suppressUi && !_ticketOverviewAutoContinueActive)
|
||||
{
|
||||
Show();
|
||||
Activate();
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
try
|
||||
@@ -994,14 +1008,17 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
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)
|
||||
return Task.CompletedTask;
|
||||
|
||||
if (suppressUi)
|
||||
BeginTicketOverviewAutoContinue(TimeSpan.FromSeconds(6));
|
||||
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
@@ -1012,10 +1029,19 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
if (_result is null || _result.Count == 0 || _result.First().Value.Count == 0)
|
||||
{
|
||||
LogEntry($"No corresponding user could be found for ticket '{ticketName}'", LogLevels.Warning);
|
||||
if (suppressUi)
|
||||
EndTicketOverviewAutoContinue(showSearch: true);
|
||||
return;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
Type = enumF4sdSearchResultClass.Ticket,
|
||||
@@ -1040,15 +1066,96 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
var filteredResults = new cFilteredResults(_result) { AutoContinue = true, PreSelectedRelation = _ticketRelation };
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (_ticketOverviewNotificationScopesPrimed.Add(scope))
|
||||
@@ -1266,72 +1373,6 @@ namespace FasdDesktopUi.Pages.SearchPage
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.Dispatcher.Invoke(new Action(() =>
|
||||
|
||||
Reference in New Issue
Block a user