360 lines
13 KiB
C#
360 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
|
|
using C4IT.FASD.Base;
|
|
using C4IT.FASD.Cockpit.Communication;
|
|
using C4IT.MultiLanguage;
|
|
using FasdDesktopUi.Basics.Services.RelationService;
|
|
using FasdDesktopUi.Basics.Services.SupportCaseSearchService;
|
|
using static C4IT.Logging.cLogManager;
|
|
|
|
|
|
|
|
namespace FasdDesktopUi.Basics
|
|
{
|
|
public interface ISearchUiProvider
|
|
{
|
|
SupportCaseSearchService SearchService { get; }
|
|
void SetSearchHistoryVisibility(bool isVisible);
|
|
void ShowLoadingTextItem(string itemText);
|
|
void ShowSearchRelations(cSearchHistorySearchResultEntry SearchHistoryEntry, IRelationService relationService, ISearchUiProvider SearchUiProvider);
|
|
void SetPendingInformationClasses(HashSet<enumFasdInformationClass> informationClasses);
|
|
void UpdatePendingInformationClasses(HashSet<enumFasdInformationClass> informationClasses);
|
|
}
|
|
|
|
public class cSearchManager
|
|
{
|
|
public const int constMaxHistoryEntryCount = 5; // max. number of entries in the search result history
|
|
public const int RefreshPeriod = 60; // time in seconds until the data should be refreshed
|
|
|
|
private static cSearchManager _Instance = null;
|
|
public static cSearchManager Instance
|
|
{
|
|
get
|
|
{
|
|
return (_Instance is null) ? _Instance = new cSearchManager() : _Instance;
|
|
}
|
|
}
|
|
|
|
public List<cSearchHistoryEntryBase> HistoryList { get; private set; } = new List<cSearchHistoryEntryBase>();
|
|
|
|
private cSearchManager()
|
|
{
|
|
}
|
|
|
|
public void AddEntry(cSearchHistoryEntryBase Entry)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
// restict the max. history length
|
|
while (HistoryList.Count >= constMaxHistoryEntryCount)
|
|
HistoryList.RemoveAt(0);
|
|
|
|
// check if we have already the same entry in the list
|
|
cSearchHistoryEntryBase alreadyExists = null;
|
|
foreach (var _entry in HistoryList)
|
|
if (_entry.DisplayText == Entry.DisplayText)
|
|
{
|
|
alreadyExists = _entry;
|
|
break;
|
|
}
|
|
// and remove the duplacated entry
|
|
if (alreadyExists != null)
|
|
HistoryList.Remove(alreadyExists);
|
|
|
|
// and the new entry at least
|
|
HistoryList.Add(Entry);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
public void ReplaceEntry(cSearchHistoryEntryBase Entry, cSearchHistoryEntryBase EntryToReplace)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
HistoryList.Remove(EntryToReplace);
|
|
AddEntry(Entry);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
private class cUserInfo
|
|
{
|
|
internal string account;
|
|
internal string domain;
|
|
internal string type;
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (this is null && obj is null)
|
|
return true;
|
|
|
|
if (this is null || obj is null)
|
|
return false;
|
|
|
|
if (!(obj is cUserInfo userInfo))
|
|
return false;
|
|
|
|
return (type == userInfo.type && account == userInfo.account && domain == userInfo.domain);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return base.GetHashCode();
|
|
}
|
|
}
|
|
|
|
private static cUserInfo GetUserInfo(cF4sdApiSearchResultRelation searchRelation)
|
|
{
|
|
try
|
|
{
|
|
if (searchRelation?.Infos is null)
|
|
return null;
|
|
|
|
searchRelation.Infos.TryGetValue("UserAccountType", out var _accountType);
|
|
searchRelation.Infos.TryGetValue("UserAccount", out var _account);
|
|
searchRelation.Infos.TryGetValue("UserDomain", out var _domain);
|
|
switch (searchRelation.Type)
|
|
{
|
|
case enumF4sdSearchResultClass.User:
|
|
if (string.IsNullOrEmpty(_account))
|
|
searchRelation.Infos.TryGetValue("account", out _account);
|
|
if (string.IsNullOrEmpty(_domain))
|
|
searchRelation.Infos.TryGetValue("domain", out _domain);
|
|
break;
|
|
case enumF4sdSearchResultClass.Computer:
|
|
case enumF4sdSearchResultClass.MobileDevice:
|
|
case enumF4sdSearchResultClass.VirtualSession:
|
|
if (string.IsNullOrEmpty(_account))
|
|
searchRelation.Infos.TryGetValue("relation_account", out _account);
|
|
if (string.IsNullOrEmpty(_domain))
|
|
searchRelation.Infos.TryGetValue("relation_domain", out _domain);
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
return new cUserInfo()
|
|
{
|
|
account = _account,
|
|
domain = _domain,
|
|
type = _accountType
|
|
};
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add identifier to relation name, if there are relations with different user infos.
|
|
/// </summary>
|
|
/// <param name="relations"></param>
|
|
internal static void ResolveRelations(List<cF4sdApiSearchResultRelation> relations)
|
|
{
|
|
try
|
|
{
|
|
cUserInfo firstUserInfo = null;
|
|
var resolveAccount = false;
|
|
foreach (var relation in relations)
|
|
{
|
|
relation.DisplayName = relation.Name;
|
|
|
|
if (relation.Type is enumF4sdSearchResultClass.Ticket)
|
|
continue;
|
|
|
|
var userInfo = GetUserInfo(relation);
|
|
if (firstUserInfo is null)
|
|
firstUserInfo = userInfo;
|
|
|
|
resolveAccount = resolveAccount || !firstUserInfo.Equals(userInfo);
|
|
}
|
|
|
|
if (!resolveAccount)
|
|
return;
|
|
|
|
foreach (var relation in relations)
|
|
{
|
|
if (relation.Type is enumF4sdSearchResultClass.Ticket || relation.Type is enumF4sdSearchResultClass.VirtualSession || relation.Type is enumF4sdSearchResultClass.MobileDevice)
|
|
continue;
|
|
|
|
string relationName = relation.Name;
|
|
|
|
var userInfo = GetUserInfo(relation);
|
|
switch (userInfo.type)
|
|
{
|
|
case "Local":
|
|
relationName = cMultiLanguageSupport.GetItem("UserSerach.AdvancedInfo.LocalUser");
|
|
break;
|
|
case "Azure":
|
|
relationName = cMultiLanguageSupport.GetItem("UserSerach.AdvancedInfo.AzureUser");
|
|
break;
|
|
default:
|
|
relationName = cMultiLanguageSupport.GetItem("UserSerach.AdvancedInfo.AdUser");
|
|
break;
|
|
|
|
}
|
|
relationName = string.Format(relationName, relation.DisplayName, userInfo.account, userInfo.domain);
|
|
relation.DisplayName = relationName;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogException(ex);
|
|
}
|
|
}
|
|
|
|
public static async Task<List<cF4sdApiSearchResultRelation>> GetCaseRelationsAsync(List<cFasdApiSearchResultEntry> SearchResults, cF4sdApiSearchResultRelation CaseRelation = null)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var firstSearchResultData = SearchResults.First();
|
|
|
|
// get SearchResult relation data
|
|
var CaseRelations = await cFasdCockpitCommunicationBase.Instance.GetSearchResultRelations(firstSearchResultData.Type, SearchResults);
|
|
|
|
// add the passed CaseRelation if it not within the result
|
|
var addRelation = CaseRelation != null;
|
|
if (addRelation)
|
|
foreach (var _caseRelation in CaseRelations)
|
|
{
|
|
if (_caseRelation.isEqual(CaseRelation))
|
|
{
|
|
addRelation = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (addRelation)
|
|
CaseRelations.Add(CaseRelation);
|
|
|
|
// if we have no relation, create a 'dummy' relation to relate to the search result itself
|
|
if (CaseRelations?.Count == 0)
|
|
{
|
|
var _dummyRelation = new cF4sdApiSearchResultRelation(firstSearchResultData);
|
|
CaseRelations.Add(_dummyRelation);
|
|
}
|
|
|
|
if (CaseRelations?.Count > 0)
|
|
CaseRelations = CaseRelations.OrderByDescending(relation => relation.Type)
|
|
.ThenBy(relation => relation.LastUsed)
|
|
.ThenBy(relation => relation.UsingLevel)
|
|
.ToList();
|
|
|
|
return CaseRelations;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public abstract class cSearchHistoryEntryBase
|
|
{
|
|
public string DisplayText { get; private set; }
|
|
public bool isSeen { get; set; } = false;
|
|
|
|
protected DateTime LastRefresh = DateTime.MinValue;
|
|
public List<cFasdApiSearchResultEntry> SelectedSearchResult { get; private set; }
|
|
public List<cF4sdApiSearchResultRelation> Relations { get; protected set; }
|
|
|
|
public ISearchUiProvider SearchUiProvider { get; private set; }
|
|
|
|
public cSearchHistoryEntryBase(string DisplayText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, ISearchUiProvider SearchUiProvider)
|
|
{
|
|
this.DisplayText = DisplayText;
|
|
this.isSeen = isSeen;
|
|
this.SelectedSearchResult = selectedSearchResult;
|
|
this.Relations = relations;
|
|
this.SearchUiProvider = SearchUiProvider;
|
|
LastRefresh = DateTime.UtcNow;
|
|
}
|
|
|
|
public abstract Task RefreshAsync();
|
|
|
|
public bool ShouldRefresh()
|
|
{
|
|
return (DateTime.UtcNow - LastRefresh).TotalSeconds > cSearchManager.RefreshPeriod;
|
|
}
|
|
}
|
|
|
|
public class cSearchHistorySearchResultEntry : cSearchHistoryEntryBase
|
|
{
|
|
public string HeaderText { get; private set; }
|
|
|
|
public cSearchHistorySearchResultEntry(string DisplayText, string HeaderText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, ISearchUiProvider SearchUiProvider) : base(DisplayText, selectedSearchResult, relations, SearchUiProvider)
|
|
{
|
|
this.HeaderText = HeaderText;
|
|
LastRefresh = DateTime.UtcNow;
|
|
}
|
|
|
|
public async override Task RefreshAsync()
|
|
{
|
|
if (ShouldRefresh())
|
|
{
|
|
var RetVal = await cSearchManager.GetCaseRelationsAsync(SelectedSearchResult);
|
|
if (RetVal != null)
|
|
{
|
|
Relations = RetVal;
|
|
LastRefresh = DateTime.UtcNow;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class cSearchHistoryRelationEntry : cSearchHistoryEntryBase
|
|
{
|
|
public cF4sdApiSearchResultRelation SelectedRelation { get; private set; }
|
|
|
|
public cSearchHistoryRelationEntry(string DisplayText, List<cFasdApiSearchResultEntry> selectedSearchResult, List<cF4sdApiSearchResultRelation> relations, cF4sdApiSearchResultRelation selectedRealtion, ISearchUiProvider SearchUiProvider) : base(DisplayText, selectedSearchResult, relations, SearchUiProvider)
|
|
{
|
|
SelectedRelation = selectedRealtion;
|
|
}
|
|
|
|
public async override Task RefreshAsync()
|
|
{
|
|
if (ShouldRefresh())
|
|
{
|
|
var RetVal = await cSearchManager.GetCaseRelationsAsync(SelectedSearchResult, SelectedRelation);
|
|
if (RetVal != null)
|
|
{
|
|
Relations = RetVal;
|
|
LastRefresh = DateTime.UtcNow;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|