aktueller Stand
This commit is contained in:
@@ -35,7 +35,6 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
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()
|
||||
@@ -47,6 +46,7 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
BuildCategoryLookup();
|
||||
LoadTicketOverviewRelations();
|
||||
LoadGeneratedTickets();
|
||||
EnsureOverviewTicketJournalEntries();
|
||||
}
|
||||
|
||||
public override bool IsDemo() => true;
|
||||
@@ -193,11 +193,11 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadGeneratedTickets()
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = TicketOverviewDataStore.LoadTickets();
|
||||
private void LoadGeneratedTickets()
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = TicketOverviewDataStore.LoadTickets();
|
||||
foreach (var record in records)
|
||||
{
|
||||
AppendDemoTicket(record);
|
||||
@@ -268,9 +268,112 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
return;
|
||||
|
||||
var generatedTicket = ConvertToTicket(record);
|
||||
targetSample.Tickets.Add(generatedTicket);
|
||||
}
|
||||
}
|
||||
targetSample.Tickets.Add(generatedTicket);
|
||||
EnsureTicketHasMinimumDemoJournalEntries(generatedTicket);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureOverviewTicketJournalEntries()
|
||||
{
|
||||
try
|
||||
{
|
||||
var overviewTicketIds = TicketOverviewRelations.Values
|
||||
.Where(scopeMap => scopeMap != null)
|
||||
.SelectMany(scopeMap => scopeMap.Values)
|
||||
.Where(definitions => definitions != null)
|
||||
.SelectMany(definitions => definitions)
|
||||
.Where(definition => definition != null && definition.TicketId != Guid.Empty)
|
||||
.Select(definition => definition.TicketId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
foreach (var ticketId in overviewTicketIds)
|
||||
{
|
||||
var ticket = MockupData
|
||||
.FirstOrDefault(data => data != null && data.Tickets != null && data.Tickets.Any(t => t.Id == ticketId))
|
||||
?.Tickets
|
||||
.FirstOrDefault(t => t.Id == ticketId);
|
||||
|
||||
if (ticket == null)
|
||||
continue;
|
||||
|
||||
EnsureTicketHasMinimumDemoJournalEntries(ticket);
|
||||
}
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureTicketHasMinimumDemoJournalEntries(cF4SDTicket ticket)
|
||||
{
|
||||
if (ticket == null)
|
||||
return;
|
||||
|
||||
if (ticket.JournalItems == null)
|
||||
ticket.JournalItems = new List<cF4SDTicket.cTicketJournalItem>();
|
||||
|
||||
if (ticket.JournalItems.Count >= 2)
|
||||
return;
|
||||
|
||||
bool isIncident = (ticket.Name ?? string.Empty).StartsWith("INC", StringComparison.OrdinalIgnoreCase);
|
||||
var baseTime = ticket.CreationDate == default ? DateTime.Now.AddHours(-2) : ticket.CreationDate;
|
||||
|
||||
if (ticket.JournalItems.Count == 0)
|
||||
{
|
||||
ticket.JournalItems.Add(CreateDemoJournalItem(
|
||||
baseTime,
|
||||
isIncident ? "Incident erfasst" : "Ticket erfasst",
|
||||
"Der Vorgang wurde in der Ticketuebersicht erfasst und priorisiert."));
|
||||
}
|
||||
|
||||
if (ticket.JournalItems.Count < 2)
|
||||
{
|
||||
string header;
|
||||
string text;
|
||||
|
||||
switch (ticket.Status)
|
||||
{
|
||||
case enumTicketStatus.InProgress:
|
||||
header = "Bearbeitung aufgenommen";
|
||||
text = "Der Vorgang wurde einem Bearbeiter zugeordnet und die Analyse gestartet.";
|
||||
break;
|
||||
case enumTicketStatus.OnHold:
|
||||
header = "Warte auf Rueckmeldung";
|
||||
text = "Fuer die weitere Bearbeitung werden zusaetzliche Informationen vom Anwender erwartet.";
|
||||
break;
|
||||
case enumTicketStatus.New:
|
||||
header = "Sichtung durch Service Desk";
|
||||
text = "Der Vorgang wurde gesichtet und zur Bearbeitung vorbereitet.";
|
||||
break;
|
||||
case enumTicketStatus.Closed:
|
||||
header = "Abschluss dokumentiert";
|
||||
text = "Loesung und Abschluss wurden fuer den Vorgang dokumentiert.";
|
||||
break;
|
||||
default:
|
||||
header = "Status aktualisiert";
|
||||
text = "Der aktuelle Bearbeitungsstand wurde im Vorgang aktualisiert.";
|
||||
break;
|
||||
}
|
||||
|
||||
ticket.JournalItems.Add(CreateDemoJournalItem(baseTime.AddMinutes(15), header, text));
|
||||
}
|
||||
}
|
||||
|
||||
private static cF4SDTicket.cTicketJournalItem CreateDemoJournalItem(DateTime timestamp, string header, string text)
|
||||
{
|
||||
var creationTime = timestamp == default ? DateTime.Now : timestamp;
|
||||
return new cF4SDTicket.cTicketJournalItem
|
||||
{
|
||||
Header = header ?? string.Empty,
|
||||
Description = text ?? string.Empty,
|
||||
DescriptionHtml = $"<p>{text ?? string.Empty}</p>",
|
||||
IsVisibleForUser = true,
|
||||
CreationDate = creationTime,
|
||||
CreationDaysSinceNow = Math.Max(0, (int)(DateTime.Now - creationTime).TotalDays)
|
||||
};
|
||||
}
|
||||
|
||||
private static cF4SDTicket ConvertToTicket(DemoTicketRecord record)
|
||||
{
|
||||
@@ -378,27 +481,31 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
await SimulateTicketOverviewLatencyAsync(count);
|
||||
return new List<cF4sdApiSearchResultRelation>();
|
||||
}
|
||||
int requestedCount = count <= 0 ? definitions.Count : Math.Min(count, definitions.Count);
|
||||
await SimulateTicketOverviewLatencyAsync(requestedCount);
|
||||
var relations = new List<cF4sdApiSearchResultRelation>(requestedCount);
|
||||
foreach (var definition in definitions.Take(requestedCount))
|
||||
{
|
||||
var relation = new cF4sdApiSearchResultRelation
|
||||
{
|
||||
Type = enumF4sdSearchResultClass.Ticket,
|
||||
DisplayName = definition.DisplayName ?? string.Empty,
|
||||
Name = definition.DisplayName ?? string.Empty,
|
||||
int requestedCount = count <= 0 ? definitions.Count : Math.Min(count, definitions.Count);
|
||||
await SimulateTicketOverviewLatencyAsync(requestedCount);
|
||||
var relations = new List<cF4sdApiSearchResultRelation>(requestedCount);
|
||||
foreach (var definition in definitions.Take(requestedCount))
|
||||
{
|
||||
var detailTicket = FindTicketForOverviewRelation(definition);
|
||||
var summary = definition.Summary ?? string.Empty;
|
||||
if (detailTicket != null && !string.IsNullOrWhiteSpace(detailTicket.Summary))
|
||||
summary = detailTicket.Summary;
|
||||
|
||||
var relation = new cF4sdApiSearchResultRelation
|
||||
{
|
||||
Type = enumF4sdSearchResultClass.Ticket,
|
||||
DisplayName = definition.DisplayName ?? string.Empty,
|
||||
Name = definition.DisplayName ?? string.Empty,
|
||||
id = definition.TicketId,
|
||||
Status = enumF4sdSearchResultStatus.Active,
|
||||
Infos = new Dictionary<string, string>
|
||||
{
|
||||
["Summary"] = definition.Summary ?? string.Empty,
|
||||
["StatusId"] = definition.StatusId ?? string.Empty,
|
||||
["UserDisplayName"] = definition.UserDisplayName ?? string.Empty,
|
||||
["UserAccount"] = definition.UserAccount ?? string.Empty,
|
||||
["UserDomain"] = definition.UserDomain ?? string.Empty,
|
||||
[DemoTicketHasDetailsInfoKey] = HasTicketDetails(definition.TicketId).ToString()
|
||||
},
|
||||
Status = enumF4sdSearchResultStatus.Active,
|
||||
Infos = new Dictionary<string, string>
|
||||
{
|
||||
["Summary"] = summary,
|
||||
["StatusId"] = definition.StatusId ?? string.Empty,
|
||||
["UserDisplayName"] = definition.UserDisplayName ?? string.Empty,
|
||||
["UserAccount"] = definition.UserAccount ?? string.Empty,
|
||||
["UserDomain"] = definition.UserDomain ?? string.Empty
|
||||
},
|
||||
Identities = new cF4sdIdentityList
|
||||
{
|
||||
new cF4sdIdentityEntry { Class = enumFasdInformationClass.Ticket, Id = definition.TicketId },
|
||||
@@ -416,32 +523,40 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasTicketDetails(Guid ticketId)
|
||||
{
|
||||
if (ticketId == Guid.Empty)
|
||||
return false;
|
||||
|
||||
foreach (var sample in MockupData)
|
||||
{
|
||||
var tickets = sample?.Tickets;
|
||||
if (tickets == null)
|
||||
continue;
|
||||
|
||||
foreach (var ticket in tickets)
|
||||
{
|
||||
if (ticket?.Id == ticketId)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private static Task SimulateTicketOverviewLatencyAsync(int count)
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
}
|
||||
|
||||
private cF4SDTicket FindTicketForOverviewRelation(TicketOverviewRelationDefinition definition)
|
||||
{
|
||||
if (definition == null || definition.TicketId == Guid.Empty)
|
||||
return null;
|
||||
|
||||
cF4SDTicket selectedTicket = null;
|
||||
|
||||
if (definition.UserId != Guid.Empty)
|
||||
{
|
||||
var selectedData = MockupData.FirstOrDefault(data => data.SampleDataId == definition.UserId);
|
||||
if (selectedData != null && selectedData.Tickets != null)
|
||||
selectedTicket = selectedData.Tickets.FirstOrDefault(ticket => ticket.Id == definition.TicketId);
|
||||
}
|
||||
|
||||
if (selectedTicket != null)
|
||||
return selectedTicket;
|
||||
|
||||
var fallbackData = MockupData.FirstOrDefault(data =>
|
||||
data != null &&
|
||||
data.Tickets != null &&
|
||||
data.Tickets.Any(ticket => ticket.Id == definition.TicketId));
|
||||
|
||||
if (fallbackData == null || fallbackData.Tickets == null)
|
||||
return null;
|
||||
|
||||
return fallbackData.Tickets.FirstOrDefault(ticket => ticket.Id == definition.TicketId);
|
||||
}
|
||||
|
||||
private static Task SimulateTicketOverviewLatencyAsync(int count)
|
||||
{
|
||||
int baseMs = 420;
|
||||
int perItem = 100;
|
||||
int capped = Math.Max(0, Math.Min(count, 5));
|
||||
@@ -714,21 +829,115 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
return output;
|
||||
}
|
||||
|
||||
public override async Task<cFasdApiSearchResultCollection> GetUserSearchResults(string Name, List<string> SIDs)
|
||||
{
|
||||
var output = new cFasdApiSearchResultCollection();
|
||||
try
|
||||
{
|
||||
foreach (var data in MockupData)
|
||||
{
|
||||
if (data.SampleDataName.Equals(Name, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//todo: add a field in demo data
|
||||
var searchResultClass = enumF4sdSearchResultClass.User;
|
||||
output[data.SampleDataName] = new List<cFasdApiSearchResultEntry>() { new cFasdApiSearchResultEntry() { id = data.SampleDataId, Name = data.SampleDataName, DisplayName = data.SampleDataName, Type = searchResultClass } };
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<cFasdApiSearchResultCollection> GetUserSearchResults(string Name, List<string> SIDs)
|
||||
{
|
||||
var output = new cFasdApiSearchResultCollection();
|
||||
try
|
||||
{
|
||||
bool IsNameMatch(string sourceName, string requestName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourceName) || string.IsNullOrWhiteSpace(requestName))
|
||||
return false;
|
||||
|
||||
if (sourceName.Equals(requestName, StringComparison.InvariantCultureIgnoreCase))
|
||||
return true;
|
||||
|
||||
string Normalize(string value)
|
||||
{
|
||||
return string.Join(" ", (value ?? string.Empty)
|
||||
.ToLowerInvariant()
|
||||
.Replace(",", " ")
|
||||
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
|
||||
int LevenshteinDistance(string left, string right)
|
||||
{
|
||||
if (string.IsNullOrEmpty(left))
|
||||
return right?.Length ?? 0;
|
||||
if (string.IsNullOrEmpty(right))
|
||||
return left.Length;
|
||||
|
||||
int[] previous = new int[right.Length + 1];
|
||||
int[] current = new int[right.Length + 1];
|
||||
for (int j = 0; j <= right.Length; j++)
|
||||
previous[j] = j;
|
||||
|
||||
for (int i = 1; i <= left.Length; i++)
|
||||
{
|
||||
current[0] = i;
|
||||
for (int j = 1; j <= right.Length; j++)
|
||||
{
|
||||
int cost = left[i - 1] == right[j - 1] ? 0 : 1;
|
||||
current[j] = Math.Min(
|
||||
Math.Min(current[j - 1] + 1, previous[j] + 1),
|
||||
previous[j - 1] + cost);
|
||||
}
|
||||
|
||||
var temp = previous;
|
||||
previous = current;
|
||||
current = temp;
|
||||
}
|
||||
|
||||
return previous[right.Length];
|
||||
}
|
||||
|
||||
bool IsTokenMatch(string leftToken, string rightToken)
|
||||
{
|
||||
if (leftToken == rightToken)
|
||||
return true;
|
||||
|
||||
int sharedLength = Math.Min(Math.Min(leftToken.Length, rightToken.Length), 5);
|
||||
if (sharedLength >= 4 && leftToken.Substring(0, sharedLength) == rightToken.Substring(0, sharedLength))
|
||||
return true;
|
||||
|
||||
return LevenshteinDistance(leftToken, rightToken) <= 2;
|
||||
}
|
||||
|
||||
var normalizedSource = Normalize(sourceName);
|
||||
var normalizedRequest = Normalize(requestName);
|
||||
if (normalizedSource == normalizedRequest)
|
||||
return true;
|
||||
|
||||
var sourceTokens = normalizedSource.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
var requestTokens = normalizedRequest.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
if (sourceTokens.Count == 0 || requestTokens.Count == 0 || sourceTokens.Count != requestTokens.Count)
|
||||
return false;
|
||||
|
||||
var remaining = new List<string>(sourceTokens);
|
||||
foreach (var token in requestTokens)
|
||||
{
|
||||
int index = remaining.FindIndex(candidate => IsTokenMatch(candidate, token));
|
||||
if (index < 0)
|
||||
return false;
|
||||
|
||||
remaining.RemoveAt(index);
|
||||
}
|
||||
|
||||
return remaining.Count == 0;
|
||||
}
|
||||
|
||||
foreach (var data in MockupData)
|
||||
{
|
||||
if (!IsNameMatch(data.SampleDataName, Name))
|
||||
continue;
|
||||
|
||||
//todo: add a field in demo data
|
||||
var searchResultClass = enumF4sdSearchResultClass.User;
|
||||
if (!output.ContainsKey(data.SampleDataName))
|
||||
{
|
||||
output[data.SampleDataName] = new List<cFasdApiSearchResultEntry>()
|
||||
{
|
||||
new cFasdApiSearchResultEntry()
|
||||
{
|
||||
id = data.SampleDataId,
|
||||
Name = data.SampleDataName,
|
||||
DisplayName = data.SampleDataName,
|
||||
Type = searchResultClass
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
catch (Exception E)
|
||||
@@ -758,8 +967,8 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
|
||||
var output = new List<cF4sdApiSearchResultRelation>();
|
||||
|
||||
switch (resultIds.First().ToString())
|
||||
{
|
||||
switch (resultIds.First().ToString())
|
||||
{
|
||||
case constGuidOlliOffline: // Olli Offline
|
||||
output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4-NB005", DisplayName = "C4-NB005", Infos = new Dictionary<string, string>() { ["UserAccountType"] = "AD", ["UserAccount"] = "C4-NB005", ["UserDomain"] = "C4IT" }, LastUsed = DateTime.UtcNow.AddDays(-10), Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.Parse(constGuidOlliOffline) }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
|
||||
|
||||
@@ -930,18 +1139,67 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
case constGuidComputer: // Computer
|
||||
break;
|
||||
default:
|
||||
output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4IT-007", DisplayName = "C4IT-007", LastUsed = DateTime.UtcNow, Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
|
||||
break;
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
|
||||
output = output.OrderByDescending(relation => relation.LastUsed).ToList();
|
||||
return output;
|
||||
}
|
||||
|
||||
public override async Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData)
|
||||
{
|
||||
output.Add(new cF4sdApiSearchResultRelation() { id = Guid.NewGuid(), Name = "C4IT-007", DisplayName = "C4IT-007", LastUsed = DateTime.UtcNow, Type = enumF4sdSearchResultClass.Computer, UsingLevel = 1, Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = resultIds.First() }, new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Computer, Id = Guid.NewGuid() } } });
|
||||
break;
|
||||
}
|
||||
|
||||
if (resultType == enumF4sdSearchResultClass.User)
|
||||
{
|
||||
foreach (var userId in resultIds)
|
||||
{
|
||||
AppendDemoTicketRelationsForUser(userId, output);
|
||||
}
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
|
||||
output = output.OrderByDescending(relation => relation.LastUsed).ToList();
|
||||
return output;
|
||||
}
|
||||
|
||||
private void AppendDemoTicketRelationsForUser(Guid userId, List<cF4sdApiSearchResultRelation> output)
|
||||
{
|
||||
if (userId == Guid.Empty || output == null)
|
||||
return;
|
||||
|
||||
var selectedData = MockupData.FirstOrDefault(data => data?.SampleDataId == userId);
|
||||
if (selectedData?.Tickets == null)
|
||||
return;
|
||||
|
||||
foreach (var demoTicket in selectedData.Tickets)
|
||||
{
|
||||
if (demoTicket == null || demoTicket.Id == Guid.Empty)
|
||||
continue;
|
||||
|
||||
if (output.Any(relation => relation.Type == enumF4sdSearchResultClass.Ticket && relation.id == demoTicket.Id))
|
||||
continue;
|
||||
|
||||
output.Add(new cF4sdApiSearchResultRelation()
|
||||
{
|
||||
id = demoTicket.Id,
|
||||
Name = demoTicket.Name,
|
||||
DisplayName = demoTicket.Name,
|
||||
LastUsed = demoTicket.CreationDate == default ? DateTime.UtcNow : demoTicket.CreationDate.ToUniversalTime(),
|
||||
Type = enumF4sdSearchResultClass.Ticket,
|
||||
UsingLevel = 1,
|
||||
Infos = new Dictionary<string, string>()
|
||||
{
|
||||
["Summary"] = demoTicket.Summary ?? string.Empty,
|
||||
["Status"] = demoTicket.Status.ToString(),
|
||||
["StatusId"] = ((int)demoTicket.Status).ToString(),
|
||||
["Asset"] = demoTicket.Asset ?? string.Empty
|
||||
},
|
||||
Identities = new cF4sdIdentityList()
|
||||
{
|
||||
new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = userId },
|
||||
new cF4sdIdentityEntry() { Class = enumFasdInformationClass.Ticket, Id = demoTicket.Id }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
|
||||
@@ -968,14 +1226,29 @@ namespace C4IT.FASD.Cockpit.Communication
|
||||
if (selectedData is null)
|
||||
return output;
|
||||
|
||||
output = selectedData.GetHealthCardData();
|
||||
var ticketRequest = requestData.Identities.FirstOrDefault(data => data.Class is enumFasdInformationClass.Ticket);
|
||||
if (ticketRequest != null)
|
||||
{
|
||||
var selectedTicket = selectedData.Tickets.FirstOrDefault(ticket => ticket.Id == ticketRequest.Id);
|
||||
if (selectedTicket != null)
|
||||
{
|
||||
string ticketStatusString = string.Empty;
|
||||
output = selectedData.GetHealthCardData();
|
||||
var ticketRequest = requestData.Identities.FirstOrDefault(data => data.Class is enumFasdInformationClass.Ticket);
|
||||
if (ticketRequest != null)
|
||||
{
|
||||
var selectedTicket = selectedData.Tickets.FirstOrDefault(ticket => ticket.Id == ticketRequest.Id);
|
||||
|
||||
// Some demo users share the same SampleDataId; resolve by TicketId if the first user match has no ticket details.
|
||||
if (selectedTicket == null)
|
||||
{
|
||||
var fallbackData = MockupData.FirstOrDefault(data =>
|
||||
data?.Tickets != null && data.Tickets.Any(ticket => ticket?.Id == ticketRequest.Id));
|
||||
|
||||
if (fallbackData != null)
|
||||
{
|
||||
selectedData = fallbackData;
|
||||
output = selectedData.GetHealthCardData();
|
||||
selectedTicket = selectedData.Tickets.FirstOrDefault(ticket => ticket.Id == ticketRequest.Id);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTicket != null)
|
||||
{
|
||||
string ticketStatusString = string.Empty;
|
||||
switch (selectedTicket.Status)
|
||||
{
|
||||
case enumTicketStatus.Unknown:
|
||||
|
||||
@@ -108,9 +108,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
/* --- Ab hier: 5 neue Klassiker --- */
|
||||
|
||||
{
|
||||
"TileKey": "TicketsNew",
|
||||
"UseRoleScope": false,
|
||||
@@ -247,5 +244,118 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"Tickets": []
|
||||
"Tickets": [
|
||||
{
|
||||
"TicketId": "e2e49f85-1a81-47e8-935b-d76898c155f6",
|
||||
"UserId": "916db36b-fb6e-4212-81c1-e72acdab77d2",
|
||||
"TileKey": "UnassignedTickets",
|
||||
"UseRoleScope": false,
|
||||
"DisplayName": "TCK00414",
|
||||
"Summary": "Pool Notebook fuer Schulungsteilnehmer fehlt",
|
||||
"StatusId": "New",
|
||||
"UserDisplayName": "Virtual, Vera",
|
||||
"UserAccount": "VV004",
|
||||
"UserDomain": "CONTOSO",
|
||||
"Detail": {
|
||||
"AffectedUser": "Virtual, Vera",
|
||||
"Asset": "C4-NB02014",
|
||||
"Category": "42b49002-fed3-4c9b-9532-cf351df038cf",
|
||||
"Description": "Ein Pool-Notebook fuer die morgige Schulung ist nicht auffindbar. Das Ticket wurde noch keinem Bearbeiter zugewiesen.",
|
||||
"DescriptionHtml": "<p>Ein Pool-Notebook fuer die morgige Schulung ist nicht auffindbar. Das Ticket wurde noch keinem Bearbeiter zugewiesen.</p>",
|
||||
"Priority": 2,
|
||||
"Journal": [
|
||||
{
|
||||
"Header": "Ticket erstellt",
|
||||
"Description": "Demodatensatz fuer Ticketuebersicht (Eingang).",
|
||||
"DescriptionHtml": "<p>Demodatensatz fuer Ticketuebersicht (Eingang).</p>",
|
||||
"IsVisibleForUser": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"TicketId": "ebe8818e-b197-411e-b56e-40b77b623ae2",
|
||||
"UserId": "436e8d67-1b9b-4b1a-83e9-0b1e8fa0173b",
|
||||
"TileKey": "UnassignedTickets",
|
||||
"UseRoleScope": false,
|
||||
"DisplayName": "TCK00415",
|
||||
"Summary": "Etikettendrucker im Lager meldet Papierstau",
|
||||
"StatusId": "New",
|
||||
"UserDisplayName": "Anwender, Peter",
|
||||
"UserAccount": "PA010",
|
||||
"UserDomain": "CONTOSO",
|
||||
"Detail": {
|
||||
"AffectedUser": "Anwender, Peter",
|
||||
"Asset": "PRN-LAGER-03",
|
||||
"Category": "42b49002-fed3-4c9b-9532-cf351df038cf",
|
||||
"Description": "Der Etikettendrucker im Lager zeigt permanent Papierstau, obwohl kein Papier klemmt. Ticket ist neu und noch unzugewiesen.",
|
||||
"DescriptionHtml": "<p>Der Etikettendrucker im Lager zeigt permanent Papierstau, obwohl kein Papier klemmt. Ticket ist neu und noch unzugewiesen.</p>",
|
||||
"Priority": 2,
|
||||
"Journal": [
|
||||
{
|
||||
"Header": "Ticket erstellt",
|
||||
"Description": "Demodatensatz fuer Ticketuebersicht (Eingang).",
|
||||
"DescriptionHtml": "<p>Demodatensatz fuer Ticketuebersicht (Eingang).</p>",
|
||||
"IsVisibleForUser": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"TicketId": "9e1d5d1b-5a22-430e-99ea-59840257caab",
|
||||
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
|
||||
"TileKey": "UnassignedTicketsCritical",
|
||||
"UseRoleScope": false,
|
||||
"DisplayName": "TCK00416",
|
||||
"Summary": "WLAN Controller im Werk startet zyklisch neu",
|
||||
"StatusId": "InProgress",
|
||||
"UserDisplayName": "Seifert, Dominik",
|
||||
"UserAccount": "DS014",
|
||||
"UserDomain": "CONTOSO",
|
||||
"Detail": {
|
||||
"AffectedUser": "Seifert, Dominik",
|
||||
"Asset": "NET-WLC-01",
|
||||
"Category": "42b49002-fed3-4c9b-9532-cf351df038cf",
|
||||
"Description": "Der WLAN-Controller im Werk rebootet im 5-Minuten-Takt. Das Ticket ist kritisch markiert und noch nicht personell zugewiesen.",
|
||||
"DescriptionHtml": "<p>Der WLAN-Controller im Werk rebootet im 5-Minuten-Takt. Das Ticket ist kritisch markiert und noch nicht personell zugewiesen.</p>",
|
||||
"Priority": 1,
|
||||
"Journal": [
|
||||
{
|
||||
"Header": "Stoerung eingegangen",
|
||||
"Description": "Demodatensatz fuer Ticketuebersicht (Eingang Kritisch).",
|
||||
"DescriptionHtml": "<p>Demodatensatz fuer Ticketuebersicht (Eingang Kritisch).</p>",
|
||||
"IsVisibleForUser": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"TicketId": "d427dc61-9842-4464-b37a-612878d3de0f",
|
||||
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
|
||||
"TileKey": "UnassignedTicketsCritical",
|
||||
"UseRoleScope": false,
|
||||
"DisplayName": "TCK00417",
|
||||
"Summary": "SAP Buchungsjob bricht nachts wiederholt ab",
|
||||
"StatusId": "InProgress",
|
||||
"UserDisplayName": "Boss, Bernd",
|
||||
"UserAccount": "BB003",
|
||||
"UserDomain": "CONTOSO",
|
||||
"Detail": {
|
||||
"AffectedUser": "Boss, Bernd",
|
||||
"Asset": "SAP-PRD-APP02",
|
||||
"Category": "42b49002-fed3-4c9b-9532-cf351df038cf",
|
||||
"Description": "Naechtlicher Buchungsjob endet mit Fehlercode. Ticket ist kritisch und liegt im Eingang zur Erstzuweisung.",
|
||||
"DescriptionHtml": "<p>Naechtlicher Buchungsjob endet mit Fehlercode. Ticket ist kritisch und liegt im Eingang zur Erstzuweisung.</p>",
|
||||
"Priority": 1,
|
||||
"Journal": [
|
||||
{
|
||||
"Header": "Stoerung eingegangen",
|
||||
"Description": "Demodatensatz fuer Ticketuebersicht (Eingang Kritisch).",
|
||||
"DescriptionHtml": "<p>Demodatensatz fuer Ticketuebersicht (Eingang Kritisch).</p>",
|
||||
"IsVisibleForUser": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"TicketId": "2e9cb83d-ecb7-c93b-e8e4-08daaa97265f",
|
||||
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
|
||||
"DisplayName": "TCK00405",
|
||||
"Summary": "OneDrive Synchronisation bleibt haengen",
|
||||
"Summary": "Mein OneDrive synchronisiert nicht mehr",
|
||||
"UserDisplayName": "Ticket, Timo",
|
||||
"UserAccount": "TT007",
|
||||
"UserDomain": "CONTOSO",
|
||||
@@ -153,7 +153,7 @@
|
||||
"TicketId": "de403992-98cb-4476-9e04-d645ab22e6de",
|
||||
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
|
||||
"DisplayName": "TCK00411",
|
||||
"Summary": "Rueckfrage zur Passwort Ruecksetzung beantworten",
|
||||
"Summary": "Passwort muss zur\u00fcckgesetzt werden",
|
||||
"UserDisplayName": "Ticket, Timo",
|
||||
"UserAccount": "TT007",
|
||||
"UserDomain": "CONTOSO",
|
||||
@@ -175,7 +175,7 @@
|
||||
"TicketId": "de403992-98cb-4476-9e04-d645ab22e6de",
|
||||
"UserId": "42c760d6-90e8-469f-b2fe-ac7d4cc6cb0a",
|
||||
"DisplayName": "TCK00411",
|
||||
"Summary": "Rueckfrage zur Passwort Ruecksetzung beantworten",
|
||||
"Summary": "Passwort muss zur\u00fcckgesetzt werden",
|
||||
"UserDisplayName": "Ticket, Timo",
|
||||
"UserAccount": "TT007",
|
||||
"UserDomain": "CONTOSO",
|
||||
@@ -207,7 +207,7 @@
|
||||
},
|
||||
{
|
||||
"TicketId": "a8deb50d-9f15-4371-9ebc-a28791f27d5c",
|
||||
"UserId": "76f86d28-862c-4fa2-9062-8367be7fbd92",
|
||||
"UserId": "916db36b-fb6e-4212-81c1-e72acdab77d2",
|
||||
"DisplayName": "INC00402",
|
||||
"Summary": "SharePoint Bereich Vertrieb laedt extrem langsam",
|
||||
"UserDisplayName": "Virtual, Vera",
|
||||
@@ -381,7 +381,7 @@
|
||||
"Personal": [
|
||||
{
|
||||
"TicketId": "e2e49f85-1a81-47e8-935b-d76898c155f6",
|
||||
"UserId": "76f86d28-862c-4fa2-9062-8367be7fbd92",
|
||||
"UserId": "916db36b-fb6e-4212-81c1-e72acdab77d2",
|
||||
"DisplayName": "TCK00414",
|
||||
"Summary": "Pool Notebook fuer Schulungsteilnehmer fehlt",
|
||||
"UserDisplayName": "Virtual, Vera",
|
||||
@@ -403,7 +403,7 @@
|
||||
"Role": [
|
||||
{
|
||||
"TicketId": "e2e49f85-1a81-47e8-935b-d76898c155f6",
|
||||
"UserId": "76f86d28-862c-4fa2-9062-8367be7fbd92",
|
||||
"UserId": "916db36b-fb6e-4212-81c1-e72acdab77d2",
|
||||
"DisplayName": "TCK00414",
|
||||
"Summary": "Pool Notebook fuer Schulungsteilnehmer fehlt",
|
||||
"UserDisplayName": "Virtual, Vera",
|
||||
@@ -425,7 +425,7 @@
|
||||
"TicketId": "9e1d5d1b-5a22-430e-99ea-59840257caab",
|
||||
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
|
||||
"DisplayName": "TCK00416",
|
||||
"Summary": "Ueberwachung meldet sporadische Alarme",
|
||||
"Summary": "WLAN Controller im Werk startet zyklisch neu",
|
||||
"UserDisplayName": "Seifert, Dominik",
|
||||
"UserAccount": "DS014",
|
||||
"UserDomain": "CONTOSO",
|
||||
@@ -439,7 +439,7 @@
|
||||
"TicketId": "9e1d5d1b-5a22-430e-99ea-59840257caab",
|
||||
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
|
||||
"DisplayName": "TCK00416",
|
||||
"Summary": "Ueberwachung meldet sporadische Alarme",
|
||||
"Summary": "WLAN Controller im Werk startet zyklisch neu",
|
||||
"UserDisplayName": "Seifert, Dominik",
|
||||
"UserAccount": "DS014",
|
||||
"UserDomain": "CONTOSO",
|
||||
@@ -451,7 +451,7 @@
|
||||
"TicketId": "9e1d5d1b-5a22-430e-99ea-59840257caab",
|
||||
"UserId": "deece196-d8b6-4a9c-a2b9-3c2ae9c6d4ec",
|
||||
"DisplayName": "TCK00416",
|
||||
"Summary": "Ueberwachung meldet sporadische Alarme",
|
||||
"Summary": "WLAN Controller im Werk startet zyklisch neu",
|
||||
"UserDisplayName": "Seifert, Dominik",
|
||||
"UserAccount": "DS014",
|
||||
"UserDomain": "CONTOSO",
|
||||
@@ -461,7 +461,7 @@
|
||||
"TicketId": "d427dc61-9842-4464-b37a-612878d3de0f",
|
||||
"UserId": "a2164ecd-791f-482c-bea3-f089f14bec8a",
|
||||
"DisplayName": "TCK00417",
|
||||
"Summary": "Produktionsroboter steht nach Not Aus",
|
||||
"Summary": "SAP Buchungsjob bricht nachts wiederholt ab",
|
||||
"UserDisplayName": "Boss, Bernd",
|
||||
"UserAccount": "BB003",
|
||||
"UserDomain": "CONTOSO",
|
||||
|
||||
Reference in New Issue
Block a user