diff --git a/Disco.BI/BI/DeviceBI/Migration/LogMacAddressImporting.cs b/Disco.BI/BI/DeviceBI/Migration/LogMacAddressImporting.cs new file mode 100644 index 00000000..35500d7d --- /dev/null +++ b/Disco.BI/BI/DeviceBI/Migration/LogMacAddressImporting.cs @@ -0,0 +1,123 @@ +using Disco.BI.Extensions; +using Disco.Data.Repository; +using Disco.Services.Logging; +using Disco.Services.Tasks; +using Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.BI.DeviceBI.Migration +{ + public class LogMacAddressImporting : ScheduledTask + { + public override string TaskName { get { return "Migration: Logs to Device Mac Address Details"; } } + + public override bool SingleInstanceTask { get { return true; } } + public override bool CancelInitiallySupported { get { return false; } } + + #region Required Helpers + private static string RequiredFilePath(DiscoDataContext dbContext) + { + if (dbContext.DiscoConfiguration.DataStoreLocation != null) + return System.IO.Path.Combine(dbContext.DiscoConfiguration.DataStoreLocation, "_LogMacAddressImportingRequired.txt"); + else + return null; + } + + public static bool IsRequired(DiscoDataContext dbContext) + { + var requiredFilePath = RequiredFilePath(dbContext); + + if (requiredFilePath == null) + return false; + else + return System.IO.File.Exists(requiredFilePath); + } + public static void SetRequired(DiscoDataContext dbContext) + { + var requiredFilePath = RequiredFilePath(dbContext); + + if (requiredFilePath != null) + { + System.IO.File.WriteAllText(requiredFilePath, "This file exists to indicate an Importing of Mac Address from the Disco Logs is required. It will automatically be deleted when the import completes."); + System.IO.File.SetAttributes(requiredFilePath, System.IO.FileAttributes.Hidden); + } + // ELSE: Could never be required if no DataStoreLocation is set (no logs to process) + } + #endregion + + public override void InitalizeScheduledTask(DiscoDataContext dbContext) + { + if (IsRequired(dbContext)) + { + // Schedule in 15mins + var trigger = TriggerBuilder.Create() + .StartAt(DateTimeOffset.Now.AddMinutes(15)); + + this.ScheduleTask(trigger); + } + } + + public static ScheduledTaskStatus ScheduleImmediately() + { + var existingTask = ScheduledTasks.GetTaskStatuses(typeof(LogMacAddressImporting)).Where(s => s.IsRunning).FirstOrDefault(); + if (existingTask != null) + return existingTask; + + var instance = new LogMacAddressImporting(); + return instance.ScheduleTask(); + } + + protected override void ExecuteTask() + { + using (DiscoDataContext dbContext = new DiscoDataContext()) + { + Status.UpdateStatus(0, "Importing MAC Addresses", "Querying Logs for Details"); + // Load Logs + var logRetriever = new ReadLogContext() + { + Module = DeviceBI.EnrolmentLog.Current.ModuleId, + EventTypes = new List() { (int)DeviceBI.EnrolmentLog.EventTypeIds.SessionDeviceInfo } + }; + var results = logRetriever.Query(dbContext); + + Status.UpdateStatus(50, string.Format("Passing {0} logs", results.Count)); + + Dictionary> addresses = new Dictionary>(); + + foreach (var result in results.OrderBy(r => r.Timestamp)) + addresses[((string)result.Arguments[1]).ToLower()] = new Tuple((string)result.Arguments[4], (string)result.Arguments[5]); + + Status.UpdateStatus(75, string.Format("Importing {0} details", addresses.Count)); + + var devices = dbContext.Devices.Include("DeviceDetails").ToList(); + + Tuple addressResult; + foreach (var device in devices) + { + if (addresses.TryGetValue(device.SerialNumber.ToLower(), out addressResult)) + { + if (!string.IsNullOrEmpty(addressResult.Item1)) + device.DeviceDetails.LanMacAddress(device, addressResult.Item1); + if (!string.IsNullOrEmpty(addressResult.Item2)) + device.DeviceDetails.WLanMacAddress(device, addressResult.Item2); + } + } + + Status.UpdateStatus(90, "Saving to Database"); + + dbContext.SaveChanges(); + + // Finished - Remove Placeholder File + var requiredFilePath = RequiredFilePath(dbContext); + if (System.IO.File.Exists(requiredFilePath)) + System.IO.File.Delete(requiredFilePath); + } + } + + + } +} diff --git a/Disco.BI/BI/DeviceBI/Searching.cs b/Disco.BI/BI/DeviceBI/Searching.cs index 6b2c1131..2440152f 100644 --- a/Disco.BI/BI/DeviceBI/Searching.cs +++ b/Disco.BI/BI/DeviceBI/Searching.cs @@ -10,7 +10,8 @@ namespace Disco.BI.DeviceBI { public static class Searching { - private static List Search_SelectDeviceSearchResultItem(IQueryable Query, int? LimitCount = null){ + private static List Search_SelectDeviceSearchResultItem(IQueryable Query, int? LimitCount = null) + { if (LimitCount.HasValue) Query = Query.Take(LimitCount.Value); @@ -28,15 +29,34 @@ namespace Disco.BI.DeviceBI }).ToList(); } - public static List Search(DiscoDataContext dbContext, string Term, int? LimitCount = null) + public static List Search(DiscoDataContext dbContext, string Term, int? LimitCount = null, bool SearchDetails = false) { - return Search_SelectDeviceSearchResultItem(dbContext.Devices.Where(d => - d.AssetNumber.Contains(Term) || - d.ComputerName.Contains(Term) || - d.SerialNumber.Contains(Term) || - d.Location.Contains(Term) || - Term.Contains(d.SerialNumber) - ), LimitCount); + IQueryable query; + + query = null; + + if (SearchDetails) + { + query = dbContext.Devices.Where(d => + d.AssetNumber.Contains(Term) || + d.ComputerName.Contains(Term) || + d.SerialNumber.Contains(Term) || + d.Location.Contains(Term) || + Term.Contains(d.SerialNumber) || + d.DeviceDetails.Any(dd => dd.Value.Contains(Term)) + ); + } + else + { + query = dbContext.Devices.Where(d => + d.AssetNumber.Contains(Term) || + d.ComputerName.Contains(Term) || + d.SerialNumber.Contains(Term) || + d.Location.Contains(Term) || + Term.Contains(d.SerialNumber)); + } + + return Search_SelectDeviceSearchResultItem(query, LimitCount); } public static List SearchDeviceModel(DiscoDataContext dbContext, int DeviceModelId, int? LimitCount = null) diff --git a/Disco.BI/BI/Extensions/DeviceDetailExtensions.cs b/Disco.BI/BI/Extensions/DeviceDetailExtensions.cs new file mode 100644 index 00000000..f024d884 --- /dev/null +++ b/Disco.BI/BI/Extensions/DeviceDetailExtensions.cs @@ -0,0 +1,109 @@ +using Disco.Models.Repository; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace Disco.BI.Extensions +{ + public static class DeviceDetailExtensions + { + + #region Scope Declaration + + public const string ScopeHardware = "Hardware"; + + #endregion + + #region Helpers + private static string GetDetail(this IEnumerable details, string Scope, string Key) + { + if (details == null) + throw new ArgumentNullException("details"); + if (string.IsNullOrEmpty(Scope)) + throw new ArgumentNullException("Scope"); + if (string.IsNullOrEmpty(Key)) + throw new ArgumentNullException("Key"); + + var detail = details.Where(d => d.Key == Key).FirstOrDefault(); + + if (detail == null) + return null; + else + return detail.Value; + } + + private static void SetDetail(this Device device, string Scope, string Key, string Value) + { + if (device == null) + throw new ArgumentNullException("device"); + if (string.IsNullOrEmpty(Scope)) + throw new ArgumentNullException("Scope"); + if (string.IsNullOrEmpty(Key)) + throw new ArgumentNullException("Key"); + + var detail = device.DeviceDetails.Where(d => d.Scope == Scope && d.Key == Key).FirstOrDefault(); + + // No Detail Stored & Set to Null + if (detail == null && Value == null) + return; + + if (detail == null) + { + detail = new DeviceDetail() + { + DeviceSerialNumber = device.SerialNumber, + Scope = Scope, + Key = Key, + Value = Value + }; + device.DeviceDetails.Add(detail); + } + + if (detail.Value != Value) + detail.Value = Value; + } + #endregion + + #region LanMacAddress + public const string KeyLanMacAddress = "LanMacAddress"; + /// + /// Gets the LanMacAddress Device Detail Value + /// + /// The LanMacAddress or null + public static string LanMacAddress(this IEnumerable details) + { + return details.GetDetail(ScopeHardware, KeyLanMacAddress); + } + /// + /// Sets the LanMacAddress Device Detail Value + /// + public static void LanMacAddress(this IEnumerable details, Device device, string LanMacAddress) + { + device.SetDetail(ScopeHardware, KeyLanMacAddress, LanMacAddress); + } + #endregion + + #region WLanMacAddress + public const string KeyWLanMacAddress = "WLanMacAddress"; + /// + /// Gets the WLanMacAddress Device Detail Value + /// + /// The WLanMacAddress or null + public static string WLanMacAddress(this IEnumerable details) + { + return details.GetDetail(ScopeHardware, KeyWLanMacAddress); + } + /// + /// Sets the WLanMacAddress Device Detail Value + /// + public static void WLanMacAddress(this IEnumerable details, Device device, string WLanMacAddress) + { + device.SetDetail(ScopeHardware, KeyWLanMacAddress, WLanMacAddress); + } + #endregion + + } +} diff --git a/Disco.BI/Disco.BI.csproj b/Disco.BI/Disco.BI.csproj index ce03cbef..374e9ee2 100644 --- a/Disco.BI/Disco.BI.csproj +++ b/Disco.BI/Disco.BI.csproj @@ -127,6 +127,7 @@ + @@ -146,6 +147,7 @@ + @@ -256,7 +258,7 @@ - + diff --git a/Disco.Web/App_Start/AppConfig.cs b/Disco.Web/App_Start/AppConfig.cs index 612cfde2..87c6d4c8 100644 --- a/Disco.Web/App_Start/AppConfig.cs +++ b/Disco.Web/App_Start/AppConfig.cs @@ -66,7 +66,7 @@ namespace Disco.Web Disco.BI.Interop.SignalRHandlers.RepositoryMonitorNotifications.Initialize(); } - public static void InitializeUpdateEnvironment(DiscoDataContext dbContext) + public static void InitializeUpdateEnvironment(DiscoDataContext dbContext, Version PreviousVersion) { // Initialize Logging Disco.Services.Logging.LogContext.Initalize(dbContext, DiscoApplication.SchedulerFactory); @@ -83,6 +83,10 @@ namespace Disco.Web // Initialize Scheduled Tasks Disco.Services.Tasks.ScheduledTasks.InitalizeScheduledTasks(dbContext, DiscoApplication.SchedulerFactory, true); + + // Import MAC Address Migration + if (PreviousVersion != null && PreviousVersion < new Version(1, 2, 910, 0)) + Disco.BI.DeviceBI.Migration.LogMacAddressImporting.SetRequired(dbContext); } public static void DisposeEnvironment() diff --git a/Disco.Web/Areas/API/Controllers/DeviceController.cs b/Disco.Web/Areas/API/Controllers/DeviceController.cs index d2b7d595..06de2472 100644 --- a/Disco.Web/Areas/API/Controllers/DeviceController.cs +++ b/Disco.Web/Areas/API/Controllers/DeviceController.cs @@ -506,5 +506,11 @@ namespace Disco.Web.Areas.API.Controllers } #endregion + public virtual ActionResult MigrateDeviceMacAddressesFromLog() + { + var taskStatus = Disco.BI.DeviceBI.Migration.LogMacAddressImporting.ScheduleImmediately(); + return RedirectToAction(MVC.Config.Logging.TaskStatus(taskStatus.SessionId)); + } + } } diff --git a/Disco.Web/ClientSource/Style/Device.css b/Disco.Web/ClientSource/Style/Device.css index 34c639fc..6b2ea4f6 100644 --- a/Disco.Web/ClientSource/Style/Device.css +++ b/Disco.Web/ClientSource/Style/Device.css @@ -222,6 +222,36 @@ right: 220px; margin-top: -24px; } +#DeviceDetailTab-DetailsContainer > table { + border: solid 1px #e8eef4; + border-collapse: collapse; +} +#DeviceDetailTab-DetailsContainer > table > tbody > tr > td { + border: solid 1px #e8eef4; + background-color: #fff; +} +#DeviceDetailTab-DetailsContainer > table > tbody > tr:nth-child(odd) > td { + background-color: #fcfcfd; +} +#DeviceDetailTab-DetailsContainer > table > thead > tr > th, +#DeviceDetailTab-DetailsContainer > table > tbody > tr > th { + background-color: #e8eef4; + border: solid 1px #e8eef4; +} +#DeviceDetailTab-DetailsContainer > table > tbody > tr:hover > td { + background-color: #e8eef4; +} +#DeviceDetailTab-DetailsContainer > table > tfoot > tr > th, +#DeviceDetailTab-DetailsContainer > table > tfoot > tr > td { + background-color: #e8eef4; +} +#DeviceDetailTab-DetailsContainer > table > tbody > tr > th { + width: 150px; +} +#DeviceDetailTab-DetailsContainer > table > tbody > tr > th, +#DeviceDetailTab-DetailsContainer > table > tbody > tr > td { + padding: 10px 6px; +} #deviceShowResources #Attachments { padding: 0; border: 1px solid #cccccc; diff --git a/Disco.Web/ClientSource/Style/Device.less b/Disco.Web/ClientSource/Style/Device.less index ae29e7b3..d431e69c 100644 --- a/Disco.Web/ClientSource/Style/Device.less +++ b/Disco.Web/ClientSource/Style/Device.less @@ -196,6 +196,23 @@ } } +#DeviceDetailTab-DetailsContainer { + & > table { + .tableData(); + + & > tbody > tr { + & > th { + width: 150px; + } + + & > th, & > td { + padding: 10px 6px; + } + } + } +} + + #deviceShowResources { #Attachments { padding: 0; diff --git a/Disco.Web/ClientSource/Style/Device.min.css b/Disco.Web/ClientSource/Style/Device.min.css index 12296ddd..2e9f3736 100644 --- a/Disco.Web/ClientSource/Style/Device.min.css +++ b/Disco.Web/ClientSource/Style/Device.min.css @@ -1 +1 @@ -.tableData{border:solid 1px #e8eef4;border-collapse:collapse}.tableData>tbody>tr>td{border:solid 1px #e8eef4;background-color:#fff}.tableData>tbody>tr:nth-child(odd)>td{background-color:#fcfcfd}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#e8eef4;border:solid 1px #e8eef4}.tableData>tbody>tr:hover>td{background-color:#e8eef4}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#e8eef4}.tableDataDark{border:solid 1px #8db2d8;border-collapse:collapse}.tableDataDark td{border:solid 1px #8db2d8;background-color:#fff}.tableDataDark th{background-color:#8db2d8;border:solid 1px #8db2d8}.tableDataContainer{background-color:#fff}.tableDataVertical{border:solid 1px #e8eef4;border-collapse:collapse}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#e8eef4;margin:0;padding:0}.tableDataVertical>tbody>tr>th.name{width:170px;text-align:right}.tableDataVertical table.sub>tbody>tr:not(:first-child)>th,.tableDataVertical table.sub>tbody>tr:not(:first-child)>td{border-top:1px dashed #aaa}.tableDataVertical table.sub>tbody>tr>th{font-weight:normal;text-align:right}.tableDataVertical table.sub>tbody>tr>th.name{text-align:right}.icon16{display:inline-block;height:16px;width:16px;margin-left:2px;cursor:pointer}.subtleUntilHover{-moz-opacity:.3;opacity:.3}.subtleUntilHover:hover{-moz-opacity:1;opacity:1}#layout_PageHeading #Device_Show_Status{margin-left:20px;display:inline-block;height:50px;font-family:"Segoe UI",Arial,Verdana,Tahoma,sans-serif;font-weight:lighter;font-stretch:condensed;font-size:.7em;text-transform:uppercase}#layout_PageHeading #Device_Show_Status span.icon{margin-right:6px}#Device_Show #Device_Show_Subjects{table-layout:fixed}#Device_Show #Device_Show_Subjects>tbody>tr>td{padding-top:0;height:100%}#Device_Show #Device_Show_Subjects>tbody>tr>td>div{position:relative}#Device_Show #Device_Show_Subjects>tbody>tr>td>div div.status{margin-top:2px;padding-top:2px;border-top:1px dashed #ddd}#Device_Show #Device_Show_Subjects>tbody>tr>td>div input.discreet{margin-left:-2px}#Device_Show #Device_Show_Subjects>tbody>tr>td:not(:last-child){border-right:1px dashed #aaa}#Device_Show #Device_Show_Subjects .dialog{display:none}#Device_Show #Device_Show_Subjects #Device_Show_Details table.verticalHeadings>tbody>tr>td:first-child{width:104px;font-weight:bold}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_Details_Asset_Name{font-weight:bold}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_Details_Asset_Enrolled_Trusted{display:inline-block;height:16px;padding-left:16px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACWUlEQVQ4y6XRXWiSURgHcJsXa4WNNuuyiy6CoAupixERoXXhmljuxaJiFrVA1i72cVFCOSMt8rNt2YfGO5g5Z1NstWW+c4ZBq4QpqMkEbZDSCObAMprjdf90sIjxsgUdODd/zvmd5zwPCwDrf/aGB7q6utgmk8ngdruzVqt10eVyTWu1Wuk/AXK5vMpoNPpjsRgGbU8/9fbdH/J4PAuRSARKpfLKhoBYLG595nTCaDSZVjPp6TPbHQ5H0mAwfBeJRHXrAp0dna9JcqCguX2H/Xd+S625aLFYQBDE8XWBd+8/TI6Njc+vzcfGX4nLX4FOp5OuC0wGAlS53NzaPPAm2Gi32+H3+5tYJEl+pigKoVAIPp+PnpqaosPhMF1uHB2Px2mv14vya6VgMKhhHGN3d/dSMplENptFIpHA3NwcCoUCSqUSKqvScZVKBbPZHGQEFApFMZ1OI5PJIBqNrkD5fB40Ta8AlcrUajVsNpufEbh+42YxHEkh+/UbUqlZpGd/lAH8WTMzMzDd64d7NMAMDOobi/OpHqh6rqK9jcCvBQncQzK0Xm5DPn0BJ4lz6GgVIkedYAaamxqK0dEDePl4FziczehTsZGLs7BnNwdiwRac4lejvp6La83VzABv/8FF/qG9oD/WQS/fhNptHEw8rEJiuAo7ubXACAtH9m0Fu2YHxQzweEuEVIYnaiFmvQ04f1aItksi5KaP4ZFGjDB5GG/7j4LL5YYYgZYW2c/yiJbv6h/A0EvC4RjGiOsFnK4J+KgABmyjsDufL0skki8CgYCoXOLz+TWrwG+kXMkgQ6yv+QAAAABJRU5ErkJggg==);background-repeat:no-repeat}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_GenerateDocument_Container{padding-top:4px}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_GenerateDocument_Container #Device_Show_GenerateDocument{padding:0}#Device_Show #Device_Show_Subjects #Device_Show_Policies table.verticalHeadings>tbody>tr>td:first-child{width:120px;font-weight:bold}#Device_Show #Device_Show_Subjects #Device_Show_Aspects #Device_Show_Aspects_Model_Image{display:block;width:256px;height:256px;margin:0 auto}#Device_Show #Device_Show_Subjects #Device_Show_Subjects_Actions>td{padding-top:4px}#DeviceDetailTabs{margin-top:10px;border-radius:0;background-image:none;background-color:#fff;border:none;padding:0}#DeviceDetailTabs #DeviceDetailTabItems{border-radius:0;border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;border-bottom:none;padding:2px 0 0 4px;background-image:none;background-color:#eee;display:table}#DeviceDetailTabs #DeviceDetailTabItems>li{top:0;border-radius:0;margin:0 5px 0 0;padding:0;line-height:normal;margin-right:4px}#DeviceDetailTabs #DeviceDetailTabItems>li>a{padding:5px 8px}#DeviceDetailTabs div.ui-tabs-panel{border-radius:0;padding:4px;border-right:1px solid #ddd;border-bottom:1px solid #ddd;border-left:1px solid #ddd;border-top:none;background-color:#eee}#Device_Show_Policies_Profile_Actions_Update_Dialog ul li,#Device_Show_Policies_Batch_Actions_Update_Dialog ul li{background-color:#fff;padding:2px 0}#Device_Show_Policies_Profile_Actions_Update_Dialog ul li:nth-child(odd),#Device_Show_Policies_Batch_Actions_Update_Dialog ul li:nth-child(odd){background-color:#fcfcfd}#Device_Show_Policies_Profile_Actions_Update_Dialog ul li.selected,#Device_Show_Policies_Batch_Actions_Update_Dialog ul li.selected{background-color:#8db2d8;font-weight:bold}#DeviceDetailTab-JobsContainer div.jobTable{margin:-1px;border:1px solid #ddd}#DeviceDetailTab-JobsContainer .dataTables_wrapper .dataTables_filter{margin-top:-24px;-moz-opacity:1;opacity:1}#DeviceDetailTab-JobsContainer .dataTables_wrapper .dataTables_length{margin-top:-24px;-moz-opacity:1;opacity:1}#DeviceDetailTab-JobsContainer .dataTables_wrapper .dataTables_showStatusClosed{right:220px;margin-top:-24px}#deviceShowResources #Attachments{padding:0;border:1px solid #ccc;background-color:#fff}#deviceShowResources #Attachments div.attachmentOutput{height:115px;overflow:auto;font-size:.95em}#deviceShowResources #Attachments div.attachmentOutput>a{display:block;float:left;height:48px;width:221px;padding:2px;margin:2px;font-size:.9em;border:1px solid #fff;color:#000;text-decoration:none}#deviceShowResources #Attachments div.attachmentOutput>a span.comments,#deviceShowResources #Attachments div.attachmentOutput>a span.author,#deviceShowResources #Attachments div.attachmentOutput>a span.timestamp{display:block;float:left;width:168px;overflow:hidden;height:16px}#deviceShowResources #Attachments div.attachmentOutput>a span.author{color:#888;width:150px}#deviceShowResources #Attachments div.attachmentOutput>a span.timestamp{color:#888;font-style:italic}#deviceShowResources #Attachments div.attachmentOutput>a span.icon{display:block;float:left;height:48px;width:48px;margin-right:2px}#deviceShowResources #Attachments div.attachmentOutput>a span.icon img{height:48px;width:48px}#deviceShowResources #Attachments div.attachmentOutput>a:hover{background-color:#ededed;border:1px solid #ccc;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#deviceShowResources #Attachments div.attachmentOutput>a:hover span.remove{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADHklEQVQ4T22SeUgUcRTHZ/aY2dnZLdfWI4KuP+zQsja7KMraXaMsOrUghe6DMjNXN7LlSyt2EHZAqbgdZFRQ/xR0QGVqZmi6h2mnVHYYBboVbgvS8evtSkHWF74w897nvTfv9xuO+48uRAyMrpqSnNSYssD6wJxqrUxISjonG6P7cv/otNZgfDR/cXrPwcO72dXrYK5TYKXlYMdLEUShw2uZu9wl6KP61oV1NiJmaFfGKhvLtYNtziJvA9u0FWzj1t73bTvAbHZ0LF2R55INw/8qPiboI9/PnpPH5i1C98RpaCP3TJ6On8kpYMlWfJthwSvLfAQnTQebtxBtU2fkH1JqjX8aVA0alvY13oQXsUPgWbkar5o8eEjgZ0MsvpAfWlPRTjFf5hq8jRmMwKhEXIkatCJcfICXjI8NsbsbVRJq4xIQCATAGIP/wwe4x09GU4IJne86wrFAMIgHI8fCp9KgQR/pcPKaaK5YKU24IehwjFPijCCiBXvwk+CQuzreo/Ptu/DzD/ITZxEuiRqcIPayQoMiXpzIOVWSuYSm2zkVijkFXBwHT64N/s4ufO7uDtvv98OXZ0cF5UqJ2UtsGS+gkBetnF0lWQrVEhZzPLZTsoigihHxeNbcjJevX+Nlezuet7bifMI4HKVcEU3fTJyDVyGfF1O4HKXGVCZosY4aZBNQPHoM6quq4aWi1qdPw/a2tKLhbi1KEidgFzFrid2nUCMntMIGTjCe1OgcRyhRNmQ4am7eRmVdHercHrizsuHZkoX7Hg9u1d6Fr9GLK4mTsJ/YEqXo2MgJvX/nLrWUVklrXJB1qN/jRLXbDU92DqoJrCF7qVENNWncfwAX+/XDNZpeoBB7rzGkTE4wuCS9rVkp4o5CgC/ZDB/t2UZ+QW6hT26ZZUYVXV8THWC5WsqnmgF/GoSUwQuDK7T9c98IMjpoalCtBYuMATMORI9Gj48Ua1dKqBBkWyYvDPur+LfSOXUkRN2yexFRBf64eHyflYLvMy34NGosGgwxBU5BTkvvO/l/WkIHu14lm3bqjGa7bDBvUMumpRTry4X0C+L3YvcBfxOhAAAAAElFTkSuQmCC)}#deviceShowResources #Attachments div.attachmentOutput>a span.remove{display:block;float:left;height:16px;width:16px;margin-left:2px}#deviceShowResources #Attachments div.attachmentOutput>a span.remove:hover{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADG0lEQVQ4y3WTCUhUURSG35vlvnnzZsoJQyMo2nTMKdsXEtOcjKxogwhKaDFNysysJooQRzTLbIFScVrIaMEiElqgMjUzsnEWl1apbNG0dCqcJiarv+NEgWEPfnj3nO/+5567cAC4f3XOb5ChfFrkemvMgn0PoufllhkmJZ2R/Mf0xfYanFTr9A/nL77ozT3oxZVrgOUEUFAEHC2AJz3zm8M495KFaUf3aXDaLyCqc+WqdqSZgKRk0iZg/UYgcePv8aYtwFYTWpYu/2CRdMZeBkeYdmTrrDnvEbsIXZNnoInknRqOn5ExQORsdEcY8dI4H54p4UDsQjRNj+g8IFfr/xqUDx5W8iV0Ap4HDoV9xWq8rLWjnsBPukB8JtXPnodmijnj1uBNwBC4Q8JQOnBwqc9gLy/qH+kCvVaFiKogA9xuN3o+V1sbbOOnotYwAR1vW3wxt8eDB/qxcCpUqNEO6DbzKgOXJxcTrjMNjnBynGICGtIz8JPgHnW2tKLjzVvf/w/SY3MWLggqHCP2skyFLF7YwJkV4p58qm7iFMjjZLBQV/a0rXB1dOJTV5dPLpcLzm0mFFOugJhsYgt5hkxeyOVMCjEnUyliMcdjMyWzCCoODsXTujq8ePUKL5qb8ayxEWcN43CYcllUPYm43bwC23lhP5cqV60rZGrEk0EKAXmjx+B+eQUcNKnxyROfHA2NqLlThfywidhJzFpi98iUSO1pIYFj+uMqzbdDlCgcOhyVN26hrLoa1TY7bMkpsG9Ixj27HTer7sBpdaA0bApyiM2XC92JHDP4jnGnUiwpozbOSRrczzCjwmaDPSUVFQRWkhxkVEkm1py9KOnXD1ep+i6ZcPnvPYjj2AiLqG2vkwu4LWNwRkbDSX02kZ6TGmjJDVHRKKfjq6UNLFKKHTQnqNdVXsmz8GJ1/3evmYQWCnuUamBAAOA/CF6VFu0Ua5aLKGZSexzPZvX5mJZxylHpgub8Xb+BX11BofgeFYPvM434GDIWNbqAr2YmlSzjWPB/X+MfLaGNXaeQ4ndo/LNNki47QSnFL+VYSF/sL7crTEWWnWvrAAAAAElFTkSuQmCC)}#deviceShowResources #Attachments div.attachmentInput{border-top:1px solid #ccc;height:40px;background-color:#fff;padding:3px}#deviceShowResources #Attachments div.attachmentInput span.action{display:block;margin:2px 4px 0 0;height:32px;width:32px;cursor:pointer;float:right;border:1px solid #fff;padding:3px;background-repeat:no-repeat;background-position:2px 3px}#deviceShowResources #Attachments div.attachmentInput span.action:hover{background-color:#ededed;border:1px solid #ccc;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#deviceShowResources #Attachments div.attachmentInput span.upload{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFPUlEQVRYw7VXayzkVxRfy4yKTj0aj6JWJISuR9EiWj5IFZt4pB+kLYmdbEJEJpp2daeIJkRNMx7xqFcl0iXxaKwVj8ishhG+eARr10wY6hVMx3gM1mNxeo7YRDfzNr3Jyfzn/u/939899/x+59xbAHDLEIbNxNHRMSQ5OTmvuLi4pbS0tDU1NbXA3d09FN8ZqZxniMVZLJZvSUnJ0NHREVA7PDwEhUIBb1pNTU2PtbW1+/8CwMvLiz07O/uKFqqrq9sNDAzstLCw4Jubm/Pd3NyeZGdnb56dncH09LQUQfgaFIC9vX30+vr6uUwmg5CQkD509Rdo75HL0W6jWaJF+/n5CRcXF0EgEEiMjIw+MAgAbM7d3d1/y6QywAU68b+NmrFeYWFhwtPTU8jIyKi/MQDaXU5OjoDcHhsb+4x2fdX/jqqAwxbf0dFxNj4+vofPtjcCgO7+gRbn8/lSS0vLjPT09KrOp09F/f39S9XV1QOhoaFsXITxFoD3cfcv8MgA2RKuNwAzM7MgsVh8MDAwAAkJCRI8230CIxKJYHh4GLa2ti4jv6CggI7F7BoABlJ0cHNzEzA4v9ELADar1tZWkVQqBS6Xe4G/F/Pz8xAdHT2KwZWN7zkODg7NVVVVr87PzyErK6vp2lxTnDO2vLwMOCZeLwBsNvu3K9fDxMQEjI2NgZ2dXSl+3OnaQtZo3Pr6+qNt+TZ4enreu+q/09nZuUdeQrA+OgNwdXX9en9/H5qbm+Hx48dAO/fw8PiddqbEUyyMg66VlRVg379fQ32+vr4Z5Lnc3Nzn/zkabRY3MTHxmJmZ2UExgfz8fKBAiomJ+Usd9fCcc+fm5gDluB3HOSLwtcnJSXB2dv5JJxoS5crLy58dHx9DXl4eLCwsAMquFPs/VjcvPDy8dHV1FeLi4v7E6O+V4e7j4+MHiQ06AYiIiPiRzh2TC/T19YFQKASUWo4G0GZlZWUvpqamyAOLBATnb2N/sE5S7OTk9KVcLn/d09MDlZWVl+fu4+PTSIKjbh7GRuqCZIGSEAwNDV2gPgDmgYc6J6PMzMxW0nDk9MXa2hqkpaW9vB7xyozBYNzt7e3dHRkZuQxYiURCUv2HKtBqzx75yk1MTFwmFzY1Nb1G+sRrcL1RFpcr2NzYgNraWlheWgIOhyOmvKFXPYDtM3S/ggLP1tb2F3WFBZm/v/93BLaxsRFGR0ehoaHhBEF/pXYNdRUOj8cTUgCi0hHlWGqLEgvW5+j2EwrS9vb2SwB29vY/a2SZqhcoJFxaHClH0fuppqjHceO0exKpJXQ96kQ/9r+rFwAmkxmMCeeIdoGUe6gFVX8lnpPrUbCAV8iT4eKfaJVflHUidxtp9ygiAk2Uo927uLhUFBUVnVDkd3V1nZuamj7QOsEpy3iYNJZINq2srBK0zJKeKDT/EGVR8yk/3L4JgLuDg4PHLS0tB/j8oTYfSUpKqtuWyyElJeWltnPUAfDHKD5FEaHgs9T0gYCAAA4lJ6yEdnF8hM7lnRIAd1D5VijfI/eDNVRH/pjfD0jzsS54pFd9qQQAMygoqJ3Eh1dYSKU2U0WKdseiQ0QlVmRkJI0zNwiAKxAxWD5t7ezsAGa1IaTiR9dLK6xyvu3q7pYeHhwAFqQktZ56l/cqAJgaGxt/z+cXHSr2FEA3n8qKihEsRnoxOCUbqPVkmOdXcGzoje6U6vhNRWZUVNTztra2szmxGIhmVAei6u17e3s/wfchN77UarrxknvRHuAFtMjGxqacwWQ8omjXlBsMAuAtMMYEyFDX+Tf2LzGXbu1DZYkMAAAAAElFTkSuQmCC)}#deviceShowResources #Attachments div.attachmentInput span.photo{background-image:url(data:image/png;base64,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)}#deviceImport #ImportFile{width:100%}#deviceImport #documentation{width:700px;margin:20px auto}#deviceImport #documentation>table>thead>tr>th:first-child{width:100px}#deviceImportReview #errorMessage{font-weight:bold;color:red}#deviceImportReview #devicesNavigation{margin-top:15px;text-align:right}#deviceImportReview #devicesNavigation ul{display:inline-block;padding:1px;border:1px solid #bbb}#deviceImportReview #devicesNavigation ul li{display:inline-block;padding:1px 6px;margin:0}#deviceImportReview #devicesNavigation ul li.statusError{background-color:#ffd3d3}#deviceImportReview #devicesNavigation ul li.statusUpdate{background-color:#d3f3ff}#deviceImportReview #devicesNavigation ul li.statusNew{background-color:#d9ffb4}#deviceImportReview #devices{border:solid 1px #e8eef4;border-collapse:collapse;margin-top:6px}#deviceImportReview #devices>tbody>tr>td{border:solid 1px #e8eef4;background-color:#fff}#deviceImportReview #devices>tbody>tr:nth-child(odd)>td{background-color:#fcfcfd}#deviceImportReview #devices>thead>tr>th,#deviceImportReview #devices>tbody>tr>th{background-color:#e8eef4;border:solid 1px #e8eef4}#deviceImportReview #devices>tbody>tr:hover>td{background-color:#e8eef4}#deviceImportReview #devices>tfoot>tr>th,#deviceImportReview #devices>tfoot>tr>td{background-color:#e8eef4}#deviceImportReview #devices>tbody td{vertical-align:middle;min-height:32px}#deviceImportReview #devices>tbody tr.statusError td{background-color:#ffd3d3}#deviceImportReview #devices>tbody tr.statusUpdate td{background-color:#d3f3ff}#deviceImportReview #devices>tbody tr.statusNew td{background-color:#d9ffb4}#deviceImportReview #devices>tbody tr td.action{font-weight:bold}#deviceImportReview #devices>tbody tr td.serialNumber{font-family:Consolas,"Courier New",monospace;font-weight:bold}#deviceImportReview #devices>tbody tr td.model img.modelImage{width:32px;height:32px;margin-right:2px}#deviceImportReview #devices>tbody .error{font-weight:bold} \ No newline at end of file +.tableData{border:solid 1px #e8eef4;border-collapse:collapse}.tableData>tbody>tr>td{border:solid 1px #e8eef4;background-color:#fff}.tableData>tbody>tr:nth-child(odd)>td{background-color:#fcfcfd}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#e8eef4;border:solid 1px #e8eef4}.tableData>tbody>tr:hover>td{background-color:#e8eef4}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#e8eef4}.tableDataDark{border:solid 1px #8db2d8;border-collapse:collapse}.tableDataDark td{border:solid 1px #8db2d8;background-color:#fff}.tableDataDark th{background-color:#8db2d8;border:solid 1px #8db2d8}.tableDataContainer{background-color:#fff}.tableDataVertical{border:solid 1px #e8eef4;border-collapse:collapse}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#e8eef4;margin:0;padding:0}.tableDataVertical>tbody>tr>th.name{width:170px;text-align:right}.tableDataVertical table.sub>tbody>tr:not(:first-child)>th,.tableDataVertical table.sub>tbody>tr:not(:first-child)>td{border-top:1px dashed #aaa}.tableDataVertical table.sub>tbody>tr>th{font-weight:normal;text-align:right}.tableDataVertical table.sub>tbody>tr>th.name{text-align:right}.icon16{display:inline-block;height:16px;width:16px;margin-left:2px;cursor:pointer}.subtleUntilHover{-moz-opacity:.3;opacity:.3}.subtleUntilHover:hover{-moz-opacity:1;opacity:1}#layout_PageHeading #Device_Show_Status{margin-left:20px;display:inline-block;height:50px;font-family:"Segoe UI",Arial,Verdana,Tahoma,sans-serif;font-weight:lighter;font-stretch:condensed;font-size:.7em;text-transform:uppercase}#layout_PageHeading #Device_Show_Status span.icon{margin-right:6px}#Device_Show #Device_Show_Subjects{table-layout:fixed}#Device_Show #Device_Show_Subjects>tbody>tr>td{padding-top:0;height:100%}#Device_Show #Device_Show_Subjects>tbody>tr>td>div{position:relative}#Device_Show #Device_Show_Subjects>tbody>tr>td>div div.status{margin-top:2px;padding-top:2px;border-top:1px dashed #ddd}#Device_Show #Device_Show_Subjects>tbody>tr>td>div input.discreet{margin-left:-2px}#Device_Show #Device_Show_Subjects>tbody>tr>td:not(:last-child){border-right:1px dashed #aaa}#Device_Show #Device_Show_Subjects .dialog{display:none}#Device_Show #Device_Show_Subjects #Device_Show_Details table.verticalHeadings>tbody>tr>td:first-child{width:104px;font-weight:bold}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_Details_Asset_Name{font-weight:bold}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_Details_Asset_Enrolled_Trusted{display:inline-block;height:16px;padding-left:16px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACWUlEQVQ4y6XRXWiSURgHcJsXa4WNNuuyiy6CoAupixERoXXhmljuxaJiFrVA1i72cVFCOSMt8rNt2YfGO5g5Z1NstWW+c4ZBq4QpqMkEbZDSCObAMprjdf90sIjxsgUdODd/zvmd5zwPCwDrf/aGB7q6utgmk8ngdruzVqt10eVyTWu1Wuk/AXK5vMpoNPpjsRgGbU8/9fbdH/J4PAuRSARKpfLKhoBYLG595nTCaDSZVjPp6TPbHQ5H0mAwfBeJRHXrAp0dna9JcqCguX2H/Xd+S625aLFYQBDE8XWBd+8/TI6Njc+vzcfGX4nLX4FOp5OuC0wGAlS53NzaPPAm2Gi32+H3+5tYJEl+pigKoVAIPp+PnpqaosPhMF1uHB2Px2mv14vya6VgMKhhHGN3d/dSMplENptFIpHA3NwcCoUCSqUSKqvScZVKBbPZHGQEFApFMZ1OI5PJIBqNrkD5fB40Ta8AlcrUajVsNpufEbh+42YxHEkh+/UbUqlZpGd/lAH8WTMzMzDd64d7NMAMDOobi/OpHqh6rqK9jcCvBQncQzK0Xm5DPn0BJ4lz6GgVIkedYAaamxqK0dEDePl4FziczehTsZGLs7BnNwdiwRac4lejvp6La83VzABv/8FF/qG9oD/WQS/fhNptHEw8rEJiuAo7ubXACAtH9m0Fu2YHxQzweEuEVIYnaiFmvQ04f1aItksi5KaP4ZFGjDB5GG/7j4LL5YYYgZYW2c/yiJbv6h/A0EvC4RjGiOsFnK4J+KgABmyjsDufL0skki8CgYCoXOLz+TWrwG+kXMkgQ6yv+QAAAABJRU5ErkJggg==);background-repeat:no-repeat}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_GenerateDocument_Container{padding-top:4px}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_GenerateDocument_Container #Device_Show_GenerateDocument{padding:0}#Device_Show #Device_Show_Subjects #Device_Show_Policies table.verticalHeadings>tbody>tr>td:first-child{width:120px;font-weight:bold}#Device_Show #Device_Show_Subjects #Device_Show_Aspects #Device_Show_Aspects_Model_Image{display:block;width:256px;height:256px;margin:0 auto}#Device_Show #Device_Show_Subjects #Device_Show_Subjects_Actions>td{padding-top:4px}#DeviceDetailTabs{margin-top:10px;border-radius:0;background-image:none;background-color:#fff;border:none;padding:0}#DeviceDetailTabs #DeviceDetailTabItems{border-radius:0;border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;border-bottom:none;padding:2px 0 0 4px;background-image:none;background-color:#eee;display:table}#DeviceDetailTabs #DeviceDetailTabItems>li{top:0;border-radius:0;margin:0 5px 0 0;padding:0;line-height:normal;margin-right:4px}#DeviceDetailTabs #DeviceDetailTabItems>li>a{padding:5px 8px}#DeviceDetailTabs div.ui-tabs-panel{border-radius:0;padding:4px;border-right:1px solid #ddd;border-bottom:1px solid #ddd;border-left:1px solid #ddd;border-top:none;background-color:#eee}#Device_Show_Policies_Profile_Actions_Update_Dialog ul li,#Device_Show_Policies_Batch_Actions_Update_Dialog ul li{background-color:#fff;padding:2px 0}#Device_Show_Policies_Profile_Actions_Update_Dialog ul li:nth-child(odd),#Device_Show_Policies_Batch_Actions_Update_Dialog ul li:nth-child(odd){background-color:#fcfcfd}#Device_Show_Policies_Profile_Actions_Update_Dialog ul li.selected,#Device_Show_Policies_Batch_Actions_Update_Dialog ul li.selected{background-color:#8db2d8;font-weight:bold}#DeviceDetailTab-JobsContainer div.jobTable{margin:-1px;border:1px solid #ddd}#DeviceDetailTab-JobsContainer .dataTables_wrapper .dataTables_filter{margin-top:-24px;-moz-opacity:1;opacity:1}#DeviceDetailTab-JobsContainer .dataTables_wrapper .dataTables_length{margin-top:-24px;-moz-opacity:1;opacity:1}#DeviceDetailTab-JobsContainer .dataTables_wrapper .dataTables_showStatusClosed{right:220px;margin-top:-24px}#DeviceDetailTab-DetailsContainer>table{border:solid 1px #e8eef4;border-collapse:collapse}#DeviceDetailTab-DetailsContainer>table>tbody>tr>td{border:solid 1px #e8eef4;background-color:#fff}#DeviceDetailTab-DetailsContainer>table>tbody>tr:nth-child(odd)>td{background-color:#fcfcfd}#DeviceDetailTab-DetailsContainer>table>thead>tr>th,#DeviceDetailTab-DetailsContainer>table>tbody>tr>th{background-color:#e8eef4;border:solid 1px #e8eef4}#DeviceDetailTab-DetailsContainer>table>tbody>tr:hover>td{background-color:#e8eef4}#DeviceDetailTab-DetailsContainer>table>tfoot>tr>th,#DeviceDetailTab-DetailsContainer>table>tfoot>tr>td{background-color:#e8eef4}#DeviceDetailTab-DetailsContainer>table>tbody>tr>th{width:150px}#DeviceDetailTab-DetailsContainer>table>tbody>tr>th,#DeviceDetailTab-DetailsContainer>table>tbody>tr>td{padding:10px 6px}#deviceShowResources #Attachments{padding:0;border:1px solid #ccc;background-color:#fff}#deviceShowResources #Attachments div.attachmentOutput{height:115px;overflow:auto;font-size:.95em}#deviceShowResources #Attachments div.attachmentOutput>a{display:block;float:left;height:48px;width:221px;padding:2px;margin:2px;font-size:.9em;border:1px solid #fff;color:#000;text-decoration:none}#deviceShowResources #Attachments div.attachmentOutput>a span.comments,#deviceShowResources #Attachments div.attachmentOutput>a span.author,#deviceShowResources #Attachments div.attachmentOutput>a span.timestamp{display:block;float:left;width:168px;overflow:hidden;height:16px}#deviceShowResources #Attachments div.attachmentOutput>a span.author{color:#888;width:150px}#deviceShowResources #Attachments div.attachmentOutput>a span.timestamp{color:#888;font-style:italic}#deviceShowResources #Attachments div.attachmentOutput>a span.icon{display:block;float:left;height:48px;width:48px;margin-right:2px}#deviceShowResources #Attachments div.attachmentOutput>a span.icon img{height:48px;width:48px}#deviceShowResources #Attachments div.attachmentOutput>a:hover{background-color:#ededed;border:1px solid #ccc;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#deviceShowResources #Attachments div.attachmentOutput>a:hover span.remove{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADHklEQVQ4T22SeUgUcRTHZ/aY2dnZLdfWI4KuP+zQsja7KMraXaMsOrUghe6DMjNXN7LlSyt2EHZAqbgdZFRQ/xR0QGVqZmi6h2mnVHYYBboVbgvS8evtSkHWF74w897nvTfv9xuO+48uRAyMrpqSnNSYssD6wJxqrUxISjonG6P7cv/otNZgfDR/cXrPwcO72dXrYK5TYKXlYMdLEUShw2uZu9wl6KP61oV1NiJmaFfGKhvLtYNtziJvA9u0FWzj1t73bTvAbHZ0LF2R55INw/8qPiboI9/PnpPH5i1C98RpaCP3TJ6On8kpYMlWfJthwSvLfAQnTQebtxBtU2fkH1JqjX8aVA0alvY13oQXsUPgWbkar5o8eEjgZ0MsvpAfWlPRTjFf5hq8jRmMwKhEXIkatCJcfICXjI8NsbsbVRJq4xIQCATAGIP/wwe4x09GU4IJne86wrFAMIgHI8fCp9KgQR/pcPKaaK5YKU24IehwjFPijCCiBXvwk+CQuzreo/Ptu/DzD/ITZxEuiRqcIPayQoMiXpzIOVWSuYSm2zkVijkFXBwHT64N/s4ufO7uDtvv98OXZ0cF5UqJ2UtsGS+gkBetnF0lWQrVEhZzPLZTsoigihHxeNbcjJevX+Nlezuet7bifMI4HKVcEU3fTJyDVyGfF1O4HKXGVCZosY4aZBNQPHoM6quq4aWi1qdPw/a2tKLhbi1KEidgFzFrid2nUCMntMIGTjCe1OgcRyhRNmQ4am7eRmVdHercHrizsuHZkoX7Hg9u1d6Fr9GLK4mTsJ/YEqXo2MgJvX/nLrWUVklrXJB1qN/jRLXbDU92DqoJrCF7qVENNWncfwAX+/XDNZpeoBB7rzGkTE4wuCS9rVkp4o5CgC/ZDB/t2UZ+QW6hT26ZZUYVXV8THWC5WsqnmgF/GoSUwQuDK7T9c98IMjpoalCtBYuMATMORI9Gj48Ua1dKqBBkWyYvDPur+LfSOXUkRN2yexFRBf64eHyflYLvMy34NGosGgwxBU5BTkvvO/l/WkIHu14lm3bqjGa7bDBvUMumpRTry4X0C+L3YvcBfxOhAAAAAElFTkSuQmCC)}#deviceShowResources #Attachments div.attachmentOutput>a span.remove{display:block;float:left;height:16px;width:16px;margin-left:2px}#deviceShowResources #Attachments div.attachmentOutput>a span.remove:hover{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADG0lEQVQ4y3WTCUhUURSG35vlvnnzZsoJQyMo2nTMKdsXEtOcjKxogwhKaDFNysysJooQRzTLbIFScVrIaMEiElqgMjUzsnEWl1apbNG0dCqcJiarv+NEgWEPfnj3nO/+5567cAC4f3XOb5ChfFrkemvMgn0PoufllhkmJZ2R/Mf0xfYanFTr9A/nL77ozT3oxZVrgOUEUFAEHC2AJz3zm8M495KFaUf3aXDaLyCqc+WqdqSZgKRk0iZg/UYgcePv8aYtwFYTWpYu/2CRdMZeBkeYdmTrrDnvEbsIXZNnoInknRqOn5ExQORsdEcY8dI4H54p4UDsQjRNj+g8IFfr/xqUDx5W8iV0Ap4HDoV9xWq8rLWjnsBPukB8JtXPnodmijnj1uBNwBC4Q8JQOnBwqc9gLy/qH+kCvVaFiKogA9xuN3o+V1sbbOOnotYwAR1vW3wxt8eDB/qxcCpUqNEO6DbzKgOXJxcTrjMNjnBynGICGtIz8JPgHnW2tKLjzVvf/w/SY3MWLggqHCP2skyFLF7YwJkV4p58qm7iFMjjZLBQV/a0rXB1dOJTV5dPLpcLzm0mFFOugJhsYgt5hkxeyOVMCjEnUyliMcdjMyWzCCoODsXTujq8ePUKL5qb8ayxEWcN43CYcllUPYm43bwC23lhP5cqV60rZGrEk0EKAXmjx+B+eQUcNKnxyROfHA2NqLlThfywidhJzFpi98iUSO1pIYFj+uMqzbdDlCgcOhyVN26hrLoa1TY7bMkpsG9Ixj27HTer7sBpdaA0bApyiM2XC92JHDP4jnGnUiwpozbOSRrczzCjwmaDPSUVFQRWkhxkVEkm1py9KOnXD1ep+i6ZcPnvPYjj2AiLqG2vkwu4LWNwRkbDSX02kZ6TGmjJDVHRKKfjq6UNLFKKHTQnqNdVXsmz8GJ1/3evmYQWCnuUamBAAOA/CF6VFu0Ua5aLKGZSexzPZvX5mJZxylHpgub8Xb+BX11BofgeFYPvM434GDIWNbqAr2YmlSzjWPB/X+MfLaGNXaeQ4ndo/LNNki47QSnFL+VYSF/sL7crTEWWnWvrAAAAAElFTkSuQmCC)}#deviceShowResources #Attachments div.attachmentInput{border-top:1px solid #ccc;height:40px;background-color:#fff;padding:3px}#deviceShowResources #Attachments div.attachmentInput span.action{display:block;margin:2px 4px 0 0;height:32px;width:32px;cursor:pointer;float:right;border:1px solid #fff;padding:3px;background-repeat:no-repeat;background-position:2px 3px}#deviceShowResources #Attachments div.attachmentInput span.action:hover{background-color:#ededed;border:1px solid #ccc;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#deviceShowResources #Attachments div.attachmentInput span.upload{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFPUlEQVRYw7VXayzkVxRfy4yKTj0aj6JWJISuR9EiWj5IFZt4pB+kLYmdbEJEJpp2daeIJkRNMx7xqFcl0iXxaKwVj8ishhG+eARr10wY6hVMx3gM1mNxeo7YRDfzNr3Jyfzn/u/939899/x+59xbAHDLEIbNxNHRMSQ5OTmvuLi4pbS0tDU1NbXA3d09FN8ZqZxniMVZLJZvSUnJ0NHREVA7PDwEhUIBb1pNTU2PtbW1+/8CwMvLiz07O/uKFqqrq9sNDAzstLCw4Jubm/Pd3NyeZGdnb56dncH09LQUQfgaFIC9vX30+vr6uUwmg5CQkD509Rdo75HL0W6jWaJF+/n5CRcXF0EgEEiMjIw+MAgAbM7d3d1/y6QywAU68b+NmrFeYWFhwtPTU8jIyKi/MQDaXU5OjoDcHhsb+4x2fdX/jqqAwxbf0dFxNj4+vofPtjcCgO7+gRbn8/lSS0vLjPT09KrOp09F/f39S9XV1QOhoaFsXITxFoD3cfcv8MgA2RKuNwAzM7MgsVh8MDAwAAkJCRI8230CIxKJYHh4GLa2ti4jv6CggI7F7BoABlJ0cHNzEzA4v9ELADar1tZWkVQqBS6Xe4G/F/Pz8xAdHT2KwZWN7zkODg7NVVVVr87PzyErK6vp2lxTnDO2vLwMOCZeLwBsNvu3K9fDxMQEjI2NgZ2dXSl+3OnaQtZo3Pr6+qNt+TZ4enreu+q/09nZuUdeQrA+OgNwdXX9en9/H5qbm+Hx48dAO/fw8PiddqbEUyyMg66VlRVg379fQ32+vr4Z5Lnc3Nzn/zkabRY3MTHxmJmZ2UExgfz8fKBAiomJ+Usd9fCcc+fm5gDluB3HOSLwtcnJSXB2dv5JJxoS5crLy58dHx9DXl4eLCwsAMquFPs/VjcvPDy8dHV1FeLi4v7E6O+V4e7j4+MHiQ06AYiIiPiRzh2TC/T19YFQKASUWo4G0GZlZWUvpqamyAOLBATnb2N/sE5S7OTk9KVcLn/d09MDlZWVl+fu4+PTSIKjbh7GRuqCZIGSEAwNDV2gPgDmgYc6J6PMzMxW0nDk9MXa2hqkpaW9vB7xyozBYNzt7e3dHRkZuQxYiURCUv2HKtBqzx75yk1MTFwmFzY1Nb1G+sRrcL1RFpcr2NzYgNraWlheWgIOhyOmvKFXPYDtM3S/ggLP1tb2F3WFBZm/v/93BLaxsRFGR0ehoaHhBEF/pXYNdRUOj8cTUgCi0hHlWGqLEgvW5+j2EwrS9vb2SwB29vY/a2SZqhcoJFxaHClH0fuppqjHceO0exKpJXQ96kQ/9r+rFwAmkxmMCeeIdoGUe6gFVX8lnpPrUbCAV8iT4eKfaJVflHUidxtp9ygiAk2Uo927uLhUFBUVnVDkd3V1nZuamj7QOsEpy3iYNJZINq2srBK0zJKeKDT/EGVR8yk/3L4JgLuDg4PHLS0tB/j8oTYfSUpKqtuWyyElJeWltnPUAfDHKD5FEaHgs9T0gYCAAA4lJ6yEdnF8hM7lnRIAd1D5VijfI/eDNVRH/pjfD0jzsS54pFd9qQQAMygoqJ3Eh1dYSKU2U0WKdseiQ0QlVmRkJI0zNwiAKxAxWD5t7ezsAGa1IaTiR9dLK6xyvu3q7pYeHhwAFqQktZ56l/cqAJgaGxt/z+cXHSr2FEA3n8qKihEsRnoxOCUbqPVkmOdXcGzoje6U6vhNRWZUVNTztra2szmxGIhmVAei6u17e3s/wfchN77UarrxknvRHuAFtMjGxqacwWQ8omjXlBsMAuAtMMYEyFDX+Tf2LzGXbu1DZYkMAAAAAElFTkSuQmCC)}#deviceShowResources #Attachments div.attachmentInput span.photo{background-image:url(data:image/png;base64,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)}#deviceImport #ImportFile{width:100%}#deviceImport #documentation{width:700px;margin:20px auto}#deviceImport #documentation>table>thead>tr>th:first-child{width:100px}#deviceImportReview #errorMessage{font-weight:bold;color:red}#deviceImportReview #devicesNavigation{margin-top:15px;text-align:right}#deviceImportReview #devicesNavigation ul{display:inline-block;padding:1px;border:1px solid #bbb}#deviceImportReview #devicesNavigation ul li{display:inline-block;padding:1px 6px;margin:0}#deviceImportReview #devicesNavigation ul li.statusError{background-color:#ffd3d3}#deviceImportReview #devicesNavigation ul li.statusUpdate{background-color:#d3f3ff}#deviceImportReview #devicesNavigation ul li.statusNew{background-color:#d9ffb4}#deviceImportReview #devices{border:solid 1px #e8eef4;border-collapse:collapse;margin-top:6px}#deviceImportReview #devices>tbody>tr>td{border:solid 1px #e8eef4;background-color:#fff}#deviceImportReview #devices>tbody>tr:nth-child(odd)>td{background-color:#fcfcfd}#deviceImportReview #devices>thead>tr>th,#deviceImportReview #devices>tbody>tr>th{background-color:#e8eef4;border:solid 1px #e8eef4}#deviceImportReview #devices>tbody>tr:hover>td{background-color:#e8eef4}#deviceImportReview #devices>tfoot>tr>th,#deviceImportReview #devices>tfoot>tr>td{background-color:#e8eef4}#deviceImportReview #devices>tbody td{vertical-align:middle;min-height:32px}#deviceImportReview #devices>tbody tr.statusError td{background-color:#ffd3d3}#deviceImportReview #devices>tbody tr.statusUpdate td{background-color:#d3f3ff}#deviceImportReview #devices>tbody tr.statusNew td{background-color:#d9ffb4}#deviceImportReview #devices>tbody tr td.action{font-weight:bold}#deviceImportReview #devices>tbody tr td.serialNumber{font-family:Consolas,"Courier New",monospace;font-weight:bold}#deviceImportReview #devices>tbody tr td.model img.modelImage{width:32px;height:32px;margin-right:2px}#deviceImportReview #devices>tbody .error{font-weight:bold} \ No newline at end of file diff --git a/Disco.Web/Controllers/DeviceController.cs b/Disco.Web/Controllers/DeviceController.cs index 497aecf4..6f5e808f 100644 --- a/Disco.Web/Controllers/DeviceController.cs +++ b/Disco.Web/Controllers/DeviceController.cs @@ -118,7 +118,7 @@ namespace Disco.Web.Controllers dbContext.Configuration.LazyLoadingEnabled = true; - m.Device = dbContext.Devices + m.Device = dbContext.Devices.Include("DeviceDetails") .Where(d => d.SerialNumber == id) .FirstOrDefault(); diff --git a/Disco.Web/Controllers/SearchController.cs b/Disco.Web/Controllers/SearchController.cs index e9290e01..e402ee99 100644 --- a/Disco.Web/Controllers/SearchController.cs +++ b/Disco.Web/Controllers/SearchController.cs @@ -62,7 +62,7 @@ namespace Disco.Web.Controllers m.ErrorMessage = "A search term of at least two characters is required"; return View(m); } - m.Devices = BI.DeviceBI.Searching.Search(dbContext, term); + m.Devices = BI.DeviceBI.Searching.Search(dbContext, term, null, searchDetails); m.Jobs = BI.JobBI.Searching.Search(dbContext, term, null, true, searchDetails); m.Users = BI.UserBI.Searching.Search(dbContext, term); } @@ -125,7 +125,7 @@ namespace Disco.Web.Controllers m.ErrorMessage = "A search term of at least two characters is required"; return View(m); } - m.Devices = BI.DeviceBI.Searching.Search(dbContext, term); + m.Devices = BI.DeviceBI.Searching.Search(dbContext, term, null, searchDetails); if (m.Devices.Count == 1) { return RedirectToAction(MVC.Device.Show(m.Devices[0].SerialNumber)); diff --git a/Disco.Web/Disco.Web.csproj b/Disco.Web/Disco.Web.csproj index 97df3d3d..16c43528 100644 --- a/Disco.Web/Disco.Web.csproj +++ b/Disco.Web/Disco.Web.csproj @@ -544,6 +544,11 @@ True True + + _Details.cshtml + True + True + True True @@ -1438,6 +1443,10 @@ RazorGenerator AddOffline.generated.cs + + RazorGenerator + _Details.generated.cs + RazorGenerator _AssignmentHistory.generated.cs @@ -1933,7 +1942,7 @@ False - + diff --git a/Disco.Web/Global.asax.cs b/Disco.Web/Global.asax.cs index c788ccaf..15fad3a4 100644 --- a/Disco.Web/Global.asax.cs +++ b/Disco.Web/Global.asax.cs @@ -44,7 +44,8 @@ namespace Disco.Web using (DiscoDataContext dbContext = new DiscoDataContext()) { // Check for Post-Update - bool isVersionUpdate = dbContext.DiscoConfiguration.InstalledDatabaseVersion != Disco.BI.Interop.Community.UpdateCheck.CurrentDiscoVersion(); + var previousVersion = dbContext.DiscoConfiguration.InstalledDatabaseVersion; + bool isVersionUpdate = previousVersion != Disco.BI.Interop.Community.UpdateCheck.CurrentDiscoVersion(); bool ignoreVersionUpdate = false; if (isVersionUpdate) @@ -100,7 +101,7 @@ namespace Disco.Web FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterUpdateRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(); - AppConfig.InitializeUpdateEnvironment(dbContext); + AppConfig.InitializeUpdateEnvironment(dbContext, previousVersion); } } } diff --git a/Disco.Web/T4MVC.cs b/Disco.Web/T4MVC.cs index a4e20d0b..9854bdd5 100644 --- a/Disco.Web/T4MVC.cs +++ b/Disco.Web/T4MVC.cs @@ -1191,12 +1191,14 @@ namespace Disco.Web.Controllers { public readonly string _AssignmentHistory = "_AssignmentHistory"; public readonly string _Certificates = "_Certificates"; + public readonly string _Details = "_Details"; public readonly string _Jobs = "_Jobs"; public readonly string _Resources = "_Resources"; public readonly string _Subject = "_Subject"; } public readonly string _AssignmentHistory = "~/Views/Device/DeviceParts/_AssignmentHistory.cshtml"; public readonly string _Certificates = "~/Views/Device/DeviceParts/_Certificates.cshtml"; + public readonly string _Details = "~/Views/Device/DeviceParts/_Details.cshtml"; public readonly string _Jobs = "~/Views/Device/DeviceParts/_Jobs.cshtml"; public readonly string _Resources = "~/Views/Device/DeviceParts/_Resources.cshtml"; public readonly string _Subject = "~/Views/Device/DeviceParts/_Subject.cshtml"; @@ -3386,6 +3388,7 @@ namespace Disco.Web.Areas.API.Controllers public readonly string ImportParse = "ImportParse"; public readonly string ImportProcess = "ImportProcess"; public readonly string ExportAllDevices = "ExportAllDevices"; + public readonly string MigrateDeviceMacAddressesFromLog = "MigrateDeviceMacAddressesFromLog"; } [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] @@ -3412,6 +3415,7 @@ namespace Disco.Web.Areas.API.Controllers public const string ImportParse = "ImportParse"; public const string ImportProcess = "ImportProcess"; public const string ExportAllDevices = "ExportAllDevices"; + public const string MigrateDeviceMacAddressesFromLog = "MigrateDeviceMacAddressesFromLog"; } @@ -3845,6 +3849,15 @@ namespace Disco.Web.Areas.API.Controllers return callInfo; } + partial void MigrateDeviceMacAddressesFromLogOverride(T4MVC_System_Web_Mvc_ActionResult callInfo); + + public override System.Web.Mvc.ActionResult MigrateDeviceMacAddressesFromLog() + { + var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.MigrateDeviceMacAddressesFromLog); + MigrateDeviceMacAddressesFromLogOverride(callInfo); + return callInfo; + } + } } diff --git a/Disco.Web/Views/Device/DeviceParts/_Details.cshtml b/Disco.Web/Views/Device/DeviceParts/_Details.cshtml new file mode 100644 index 00000000..a46c150f --- /dev/null +++ b/Disco.Web/Views/Device/DeviceParts/_Details.cshtml @@ -0,0 +1,20 @@ +@model Disco.Web.Models.Device.ShowModel +
+
+ + + + + + + + + + + +
LAN MAC Address@(Model.Device.DeviceDetails.LanMacAddress() ?? "Unknown")
WLAN MAC Address@(Model.Device.DeviceDetails.WLanMacAddress() ?? "Unknown")
+
+ +
diff --git a/Disco.Web/Views/Device/DeviceParts/_Details.generated.cs b/Disco.Web/Views/Device/DeviceParts/_Details.generated.cs new file mode 100644 index 00000000..ae603919 --- /dev/null +++ b/Disco.Web/Views/Device/DeviceParts/_Details.generated.cs @@ -0,0 +1,84 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18051 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Disco.Web.Views.Device.DeviceParts +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using System.Web; + using System.Web.Helpers; + using System.Web.Mvc; + using System.Web.Mvc.Ajax; + using System.Web.Mvc.Html; + using System.Web.Routing; + using System.Web.Security; + using System.Web.UI; + using System.Web.WebPages; + using Disco.BI.Extensions; + using Disco.Models.Repository; + using Disco.Web; + using Disco.Web.Extensions; + + [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")] + [System.Web.WebPages.PageVirtualPathAttribute("~/Views/Device/DeviceParts/_Details.cshtml")] + public partial class Details : System.Web.Mvc.WebViewPage + { + public Details() + { + } + public override void Execute() + { +WriteLiteral("\r\n \r\n \r\n \r\n \r\n LAN MAC Add" + +"ress\r\n "); + + + #line 8 "..\..\Views\Device\DeviceParts\_Details.cshtml" + Write(Model.Device.DeviceDetails.LanMacAddress() ?? "Unknown"); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n \r\n WLAN " + +"MAC Address\r\n "); + + + #line 12 "..\..\Views\Device\DeviceParts\_Details.cshtml" + Write(Model.Device.DeviceDetails.WLanMacAddress() ?? "Unknown"); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n \r\n \r\n \r" + +"\n \r\n\r\n"); + + } + } +} +#pragma warning restore 1591 diff --git a/Disco.Web/Views/Device/Show.cshtml b/Disco.Web/Views/Device/Show.cshtml index f869a594..88f1a4cf 100644 --- a/Disco.Web/Views/Device/Show.cshtml +++ b/Disco.Web/Views/Device/Show.cshtml @@ -46,6 +46,7 @@
    @Html.Partial(MVC.Device.Views.DeviceParts._Jobs, Model) + @Html.Partial(MVC.Device.Views.DeviceParts._Details, Model) @Html.Partial(MVC.Device.Views.DeviceParts._AssignmentHistory, Model) @Html.Partial(MVC.Device.Views.DeviceParts._Resources, Model) @Html.Partial(MVC.Device.Views.DeviceParts._Certificates, Model) diff --git a/Disco.Web/Views/Device/Show.generated.cs b/Disco.Web/Views/Device/Show.generated.cs index 0bdd337f..40a770bd 100644 --- a/Disco.Web/Views/Device/Show.generated.cs +++ b/Disco.Web/Views/Device/Show.generated.cs @@ -2,7 +2,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18033 +// Runtime Version:4.0.30319.18051 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -155,7 +155,7 @@ WriteLiteral(" "); #line 49 "..\..\Views\Device\Show.cshtml" - Write(Html.Partial(MVC.Device.Views.DeviceParts._AssignmentHistory, Model)); + Write(Html.Partial(MVC.Device.Views.DeviceParts._Details, Model)); #line default @@ -166,7 +166,7 @@ WriteLiteral(" "); #line 50 "..\..\Views\Device\Show.cshtml" - Write(Html.Partial(MVC.Device.Views.DeviceParts._Resources, Model)); + Write(Html.Partial(MVC.Device.Views.DeviceParts._AssignmentHistory, Model)); #line default @@ -177,6 +177,17 @@ WriteLiteral(" "); #line 51 "..\..\Views\Device\Show.cshtml" + Write(Html.Partial(MVC.Device.Views.DeviceParts._Resources, Model)); + + + #line default + #line hidden +WriteLiteral("\r\n"); + +WriteLiteral(" "); + + + #line 52 "..\..\Views\Device\Show.cshtml" Write(Html.Partial(MVC.Device.Views.DeviceParts._Certificates, Model)); diff --git a/Disco.Web/Views/Shared/_SearchDialog.cshtml b/Disco.Web/Views/Shared/_SearchDialog.cshtml index 1e57214f..475d1a87 100644 --- a/Disco.Web/Views/Shared/_SearchDialog.cshtml +++ b/Disco.Web/Views/Shared/_SearchDialog.cshtml @@ -13,7 +13,7 @@ @if (Model != null) { @Html.Hidden("limit", Model) - if (Model == "jobs") + if (Model == "jobs" || Model == "devices") {