diff --git a/src/Server/Coderr.Server.Api/Core/Incidents/Queries/FindIncidentsResultItem.cs b/src/Server/Coderr.Server.Api/Core/Incidents/Queries/FindIncidentsResultItem.cs
index 908e9a31..9e9dcac6 100644
--- a/src/Server/Coderr.Server.Api/Core/Incidents/Queries/FindIncidentsResultItem.cs
+++ b/src/Server/Coderr.Server.Api/Core/Incidents/Queries/FindIncidentsResultItem.cs
@@ -31,7 +31,7 @@ protected FindIncidentsResultItem()
///
/// Id of the application that this incident belongs to
///
- public string ApplicationId { get; set; }
+ public int ApplicationId { get; set; }
///
/// Name of the application that this incident belongs to
@@ -43,6 +43,11 @@ protected FindIncidentsResultItem()
///
public DateTime CreatedAtUtc { get; set; }
+ ///
+ /// When the incident was assigned to someone.
+ ///
+ public DateTime? AssignedAtUtc { get; set; }
+
///
/// Incident id
///
diff --git a/src/Server/Coderr.Server.ReportAnalyzer/Inbound/SaveReportHandler.cs b/src/Server/Coderr.Server.ReportAnalyzer/Inbound/SaveReportHandler.cs
index fa43640e..7c63b403 100644
--- a/src/Server/Coderr.Server.ReportAnalyzer/Inbound/SaveReportHandler.cs
+++ b/src/Server/Coderr.Server.ReportAnalyzer/Inbound/SaveReportHandler.cs
@@ -64,7 +64,8 @@ public async Task BuildReportAsync(ClaimsPrincipal user, string appKey, string s
throw new InvalidCredentialException($"AppKey was not found in the database. Key '{appKey}'.");
}
- if (!ReportValidator.ValidateBody(application.SharedSecret, signatureProvidedByTheClient, reportBody))
+ // web(js) applications do not sign the body
+ if (signatureProvidedByTheClient != null && !ReportValidator.ValidateBody(application.SharedSecret, signatureProvidedByTheClient, reportBody))
{
await StoreInvalidReportAsync(appKey, signatureProvidedByTheClient, remoteAddress, reportBody);
throw new AuthenticationException(
@@ -158,6 +159,21 @@ private NewReportDTO DeserializeBody(byte[] body)
if (string.IsNullOrEmpty(dto.EnvironmentName) && !string.IsNullOrEmpty(dto.Environment))
dto.EnvironmentName = dto.Environment;
+
+ // Safeguard against malformed reports (other clients than the built in ones)
+ if (dto.Exception == null)
+ return null;
+ if (string.IsNullOrWhiteSpace(dto.Exception.Name) && string.IsNullOrWhiteSpace(dto.Exception.FullName))
+ return null;
+ if (string.IsNullOrWhiteSpace(dto.Exception.Name))
+ dto.Exception.Name = dto.Exception.FullName;
+ if (string.IsNullOrWhiteSpace(dto.Exception.FullName))
+ dto.Exception.FullName = dto.Exception.Name;
+ if (dto.Exception.BaseClasses == null)
+ dto.Exception.BaseClasses = new string[0];
+ if (dto.Exception.Namespace == null)
+ dto.Exception.Namespace = "";
+
return dto;
}
diff --git a/src/Server/Coderr.Server.SqlServer/Core/Incidents/Queries/FindIncidentResultItemMapper.cs b/src/Server/Coderr.Server.SqlServer/Core/Incidents/Queries/FindIncidentResultItemMapper.cs
index 641c4fc4..2a4ac18d 100644
--- a/src/Server/Coderr.Server.SqlServer/Core/Incidents/Queries/FindIncidentResultItemMapper.cs
+++ b/src/Server/Coderr.Server.SqlServer/Core/Incidents/Queries/FindIncidentResultItemMapper.cs
@@ -20,7 +20,7 @@ public void Map(IDataRecord source, object destination)
public void Map(IDataRecord source, FindIncidentsResultItem destination)
{
destination.ApplicationName = (string) source["ApplicationName"];
- destination.ApplicationId = source["ApplicationId"].ToString();
+ destination.ApplicationId = (int)source["ApplicationId"];
destination.IsReOpened = source["IsReopened"].Equals(1);
destination.ReportCount = (int) source["ReportCount"];
destination.CreatedAtUtc = (DateTime)source["CreatedAtUtc"];
@@ -31,6 +31,9 @@ public void Map(IDataRecord source, FindIncidentsResultItem destination)
value = source["LastReportAtUtc"];
destination.LastReportReceivedAtUtc = (DateTime) (value is DBNull ? destination.LastUpdateAtUtc : value);
+
+ value = source["AssignedAtUtc"];
+ destination.AssignedAtUtc = (DateTime?)(value is DBNull ? null : value);
}
}
}
\ No newline at end of file
diff --git a/src/Server/Coderr.Server.Web/ClientApp/boot.ts b/src/Server/Coderr.Server.Web/ClientApp/boot.ts
index 703074ef..bb7697a4 100644
--- a/src/Server/Coderr.Server.Web/ClientApp/boot.ts
+++ b/src/Server/Coderr.Server.Web/ClientApp/boot.ts
@@ -3,7 +3,6 @@ import Vue from "vue";
import VueRouter from "vue-router";
import moment from "moment";
import { AppRoot } from "./services/AppRoot"
-//import VeeValidate from 'vee-validate';
import { IUser } from "./vue-shim";
//Vue.use(VeeValidate);
diff --git a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.ts b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.ts
index 6f4ca67f..5d7bc603 100644
--- a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.ts
+++ b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.ts
@@ -27,11 +27,12 @@ export default class AnalyzeIncidentComponent extends Vue {
currentCollectionName: string = '';
created() {
+ // required for contextnavigator
+ this.incidentId = parseInt(this.$route.params.incidentId, 10);
}
mounted() {
- var incidentId = parseInt(this.$route.params.incidentId, 10);
- this.loadIncident(incidentId);
+ this.loadIncident(this.incidentId);
MyIncidents.Instance.subscribeOnSelectedIncident(this.selectIncident);
}
diff --git a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.vue.html b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.vue.html
index 038cf6a7..00271499 100644
--- a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.vue.html
+++ b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/incidents/incident.vue.html
@@ -69,7 +69,7 @@
Quick facts
diff --git a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.css b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.css
index f193e68b..5c4d056c 100644
--- a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.css
+++ b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.css
@@ -10,4 +10,8 @@
.bg-light .router-link-exact-active {
color: #333333;
font-weight: bold;
-}*/
\ No newline at end of file
+}*/
+td {
+ padding-right: 15px;
+ padding-top: 5px;
+}
\ No newline at end of file
diff --git a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.ts b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.ts
index 0d3af6bb..4cae836d 100644
--- a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.ts
+++ b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.ts
@@ -1,5 +1,7 @@
+import { PubSubService, MessageContext } from "../../services/PubSub";
import * as MenuApi from "../../services/menu/MenuApi";
-import Vue from 'vue';
+import Vue from "vue";
+import { AppRoot } from '../../services/AppRoot';
import { Component, Watch } from 'vue-property-decorator';
import { MyIncidents, IMyIncident } from "./myincidents";
@@ -18,11 +20,15 @@ export default class AnalyzeMenuComponent extends Vue {
incidents: IMyIncident[] = [];
title = '';
incidentId: number | null = null;
+ toggleMenu = false;
+ applicationId: number | null = null;
created() {
if (this.$route.params.incidentId) {
this.incidentId = parseInt(this.$route.params.incidentId, 10);
}
+ this.applicationId = AppRoot.Instance.currentApplicationId;
+ PubSubService.Instance.subscribe(MenuApi.MessagingTopics.ApplicationChanged, this.onApplicationChangedInNavMenu);
MyIncidents.Instance.subscribeOnSelectedIncident(this.onIncidentSelected);
MyIncidents.Instance.subscribeOnListChanges(this.onListChanged);
}
@@ -41,6 +47,12 @@ export default class AnalyzeMenuComponent extends Vue {
destroyed() {
MyIncidents.Instance.unsubscribe(this.onIncidentSelected);
MyIncidents.Instance.unsubscribe(this.onListChanged);
+ PubSubService.Instance.unsubscribe(MenuApi.MessagingTopics.ApplicationChanged, this.onApplicationChangedInNavMenu);
+ }
+
+ toggleIncidentMenu() {
+ this.toggleMenu = !this.toggleMenu;
+
}
private onListChanged(args: any) {
@@ -62,6 +74,20 @@ export default class AnalyzeMenuComponent extends Vue {
}
}
+ @Watch('$route.params.applicationId')
+ onAppRoute(value: string, oldValue: string) {
+ if (!value) {
+ this.applicationId = null;
+ return;
+ } else {
+ this.applicationId = parseInt(value, 10);
+ }
+ }
+ private onApplicationChangedInNavMenu(ctx: MessageContext) {
+ var body = ctx.message.body;
+ this.applicationId = body.applicationId;
+ }
+
@Watch('$route.params.incidentId')
onIncidentRoute(value: string, oldValue: string) {
if (this.$route.fullPath.indexOf('/analyze/') === -1) {
diff --git a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.vue.html b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.vue.html
index 3988147a..d244e33b 100644
--- a/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.vue.html
+++ b/src/Server/Coderr.Server.Web/ClientApp/components/analyze/menu.vue.html
@@ -1,39 +1,64 @@
-