diff --git a/Models/DashboardViewModel.cs b/Models/DashboardViewModel.cs
new file mode 100644
index 0000000..020c7e3
--- /dev/null
+++ b/Models/DashboardViewModel.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+
+namespace Disco.Plugins.ServiceTracker.Models
+{
+ ///
+ /// View model for the dashboard tile display, combining Disco Job data
+ /// with ServiceTracker metadata.
+ ///
+ public class DashboardViewModel
+ {
+ public List Tiles { get; set; }
+ public DashboardStats Stats { get; set; }
+ public ServiceTrackerConfig Config { get; set; }
+ public string CurrentFilter { get; set; }
+ public string SortBy { get; set; }
+
+ public DashboardViewModel()
+ {
+ Tiles = new List();
+ Stats = new DashboardStats();
+ }
+ }
+
+ public class DashboardTile
+ {
+ // From Disco Job
+ public int JobId { get; set; }
+ public string JobTypeDescription { get; set; }
+ public string DeviceSerialNumber { get; set; }
+ public string DeviceModelDescription { get; set; }
+ public string DeviceComputerName { get; set; }
+ public string UserId { get; set; }
+ public string UserDisplayName { get; set; }
+ public string OpenedByTechId { get; set; }
+ public string OpenedByTechName { get; set; }
+ public DateTime OpenedDate { get; set; }
+ public DateTime? ExpectedClosedDate { get; set; }
+ public string DiscoStatus { get; set; }
+
+ // From ServiceTracker
+ public string PriorityId { get; set; }
+ public string PriorityName { get; set; }
+ public string PriorityColor { get; set; }
+ public int PrioritySortOrder { get; set; }
+ public string LocationId { get; set; }
+ public string LocationName { get; set; }
+ public string LocationIcon { get; set; }
+ public string LocationColor { get; set; }
+ public string AssignedTechId { get; set; }
+ public string AssignedTechName { get; set; }
+ public DateTime? EstimatedCompletion { get; set; }
+ public DateTime? SlaDeadline { get; set; }
+ public string StatusOverride { get; set; }
+ public string Summary { get; set; }
+ public int NoteCount { get; set; }
+ public string LatestNote { get; set; }
+ public DateTime LastModifiedDate { get; set; }
+
+ // Computed
+ public bool IsSlaBreached { get; set; }
+ public bool IsSlaWarning { get; set; } // within 25% of SLA
+ public string AgeBadge { get; set; }
+ public int AgeDays { get; set; }
+ public string EtaDisplay { get; set; }
+ public DateTime SortDate { get; set; } // The date used for ordering
+ }
+
+ public class DashboardStats
+ {
+ public int TotalOpen { get; set; }
+ public int Critical { get; set; }
+ public int High { get; set; }
+ public int Medium { get; set; }
+ public int Low { get; set; }
+ public int Scheduled { get; set; }
+ public int SlaBreached { get; set; }
+ public int SlaWarning { get; set; }
+ public int AtRepairer { get; set; }
+ public int InItOffice { get; set; }
+ public int WithUser { get; set; }
+ public int AwaitingParts { get; set; }
+ public double AvgAgeDays { get; set; }
+ public int OldestJobDays { get; set; }
+ public Dictionary ByPriority { get; set; }
+ public Dictionary ByLocation { get; set; }
+ public Dictionary ByStatus { get; set; }
+ public Dictionary ByTech { get; set; }
+
+ public DashboardStats()
+ {
+ ByPriority = new Dictionary();
+ ByLocation = new Dictionary();
+ ByStatus = new Dictionary();
+ ByTech = new Dictionary();
+ }
+ }
+}