From f8fd1a58a33afe84b37a6e6b0bf4a255b367cdc1 Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Thu, 17 Jul 2025 11:40:50 +1000 Subject: [PATCH] #145 add comments for devices --- Disco.Services/Authorization/Claims.cs | 34 +- .../ClaimGroups/Device/DeviceActionsClaims.cs | 7 + .../Roles/ClaimGroups/Device/DeviceClaims.cs | 2 + Disco.Services/Devices/DeviceUpdatesHub.cs | 89 ++-- Disco.Services/Users/UserUpdatesHub.cs | 10 +- .../Areas/API/Controllers/DeviceController.cs | 83 +++- .../Areas/API/Models/Shared/CommentModel.cs | 14 + Disco.Web/ClientSource/Style/Device.css | 146 +++++- Disco.Web/ClientSource/Style/Device.less | 172 ++++++- Disco.Web/ClientSource/Style/Device.min.css | 2 +- Disco.Web/ClientSource/Style/User.css | 7 + Disco.Web/ClientSource/Style/User.less | 9 + Disco.Web/ClientSource/Style/User.min.css | 2 +- Disco.Web/Disco.Web.csproj | 35 +- .../T4MVC/API.DeviceController.generated.cs | 114 +++++ .../T4MVC/DeviceController.generated.cs | 6 +- .../T4MVC/UserController.generated.cs | 4 +- .../Views/Device/DeviceParts/_Comments.cshtml | 212 ++++++++ .../Device/DeviceParts/_Comments.generated.cs | 452 ++++++++++++++++++ .../DeviceParts/_CommentsAndJobs.cshtml | 41 ++ .../DeviceParts/_CommentsAndJobs.generated.cs | 185 +++++++ .../Views/Device/DeviceParts/_Jobs.cshtml | 12 - .../Device/DeviceParts/_Jobs.generated.cs | 90 ---- .../Device/DeviceParts/_Resources.cshtml | 116 ++--- .../DeviceParts/_Resources.generated.cs | 429 +++++++---------- Disco.Web/Views/Device/Show.cshtml | 83 +++- Disco.Web/Views/Device/Show.generated.cs | 200 +++++--- Disco.Web/Views/Job/Show.cshtml | 4 +- Disco.Web/Views/Job/Show.generated.cs | 6 +- .../{Comments.cshtml => _Comments.cshtml} | 2 +- ...ts.generated.cs => _Comments.generated.cs} | 63 +-- .../User/UserParts/_CommentsAndJobs.cshtml | 2 +- .../UserParts/_CommentsAndJobs.generated.cs | 2 +- .../Views/User/UserParts/_Resources.cshtml | 1 + .../User/UserParts/_Resources.generated.cs | 25 +- 35 files changed, 2047 insertions(+), 614 deletions(-) create mode 100644 Disco.Web/Views/Device/DeviceParts/_Comments.cshtml create mode 100644 Disco.Web/Views/Device/DeviceParts/_Comments.generated.cs create mode 100644 Disco.Web/Views/Device/DeviceParts/_CommentsAndJobs.cshtml create mode 100644 Disco.Web/Views/Device/DeviceParts/_CommentsAndJobs.generated.cs delete mode 100644 Disco.Web/Views/Device/DeviceParts/_Jobs.cshtml delete mode 100644 Disco.Web/Views/Device/DeviceParts/_Jobs.generated.cs rename Disco.Web/Views/User/UserParts/{Comments.cshtml => _Comments.cshtml} (99%) rename Disco.Web/Views/User/UserParts/{Comments.generated.cs => _Comments.generated.cs} (89%) diff --git a/Disco.Services/Authorization/Claims.cs b/Disco.Services/Authorization/Claims.cs index b302c59b..64d169d9 100644 --- a/Disco.Services/Authorization/Claims.cs +++ b/Disco.Services/Authorization/Claims.cs @@ -193,6 +193,7 @@ namespace Disco.Services.Authorization { "Device.Properties.DeviceProfile", new Tuple, Action, string, string, bool>(c => c.Device.Properties.DeviceProfile, (c, v) => c.Device.Properties.DeviceProfile = v, "Device Profile Property", "Can update property", false) }, { "Device.Properties.Location", new Tuple, Action, string, string, bool>(c => c.Device.Properties.Location, (c, v) => c.Device.Properties.Location = v, "Location Property", "Can update property", false) }, { "Device.Actions.AddAttachments", new Tuple, Action, string, string, bool>(c => c.Device.Actions.AddAttachments, (c, v) => c.Device.Actions.AddAttachments = v, "Add Attachments", "Can add attachments to devices", false) }, + { "Device.Actions.AddComments", new Tuple, Action, string, string, bool>(c => c.Device.Actions.AddComments, (c, v) => c.Device.Actions.AddComments = v, "Add Comments", "Can add device comments", false) }, { "Device.Actions.AddFlags", new Tuple, Action, string, string, bool>(c => c.Device.Actions.AddFlags, (c, v) => c.Device.Actions.AddFlags = v, "Add Device Flags", "Can add device flags", false) }, { "Device.Actions.AllowUnauthenticatedEnrol", new Tuple, Action, string, string, bool>(c => c.Device.Actions.AllowUnauthenticatedEnrol, (c, v) => c.Device.Actions.AllowUnauthenticatedEnrol = v, "Allow Unauthenticated Enrol", "Can allow devices to enrol without authentication", false) }, { "Device.Actions.AssignUser", new Tuple, Action, string, string, bool>(c => c.Device.Actions.AssignUser, (c, v) => c.Device.Actions.AssignUser = v, "Assign User", "Can update the user assignment of devices", false) }, @@ -205,12 +206,15 @@ namespace Disco.Services.Authorization { "Device.Actions.Import", new Tuple, Action, string, string, bool>(c => c.Device.Actions.Import, (c, v) => c.Device.Actions.Import = v, "Import Devices", "Can bulk import devices", false) }, { "Device.Actions.Recommission", new Tuple, Action, string, string, bool>(c => c.Device.Actions.Recommission, (c, v) => c.Device.Actions.Recommission = v, "Recommission", "Can recommission devices", false) }, { "Device.Actions.RemoveAnyAttachments", new Tuple, Action, string, string, bool>(c => c.Device.Actions.RemoveAnyAttachments, (c, v) => c.Device.Actions.RemoveAnyAttachments = v, "Remove Any Attachments", "Can remove any attachments from devices", false) }, + { "Device.Actions.RemoveAnyComments", new Tuple, Action, string, string, bool>(c => c.Device.Actions.RemoveAnyComments, (c, v) => c.Device.Actions.RemoveAnyComments = v, "Remove Any Comments", "Can remove any device comments", false) }, { "Device.Actions.RemoveFlags", new Tuple, Action, string, string, bool>(c => c.Device.Actions.RemoveFlags, (c, v) => c.Device.Actions.RemoveFlags = v, "Remove Device Flags", "Can remove device flags", false) }, { "Device.Actions.RemoveOwnAttachments", new Tuple, Action, string, string, bool>(c => c.Device.Actions.RemoveOwnAttachments, (c, v) => c.Device.Actions.RemoveOwnAttachments = v, "Remove Own Attachments", "Can remove own attachments from devices", false) }, + { "Device.Actions.RemoveOwnComments", new Tuple, Action, string, string, bool>(c => c.Device.Actions.RemoveOwnComments, (c, v) => c.Device.Actions.RemoveOwnComments = v, "Remove Own Comments", "Can remove own device comments", false) }, { "Device.Search", new Tuple, Action, string, string, bool>(c => c.Device.Search, (c, v) => c.Device.Search = v, "Search Devices", "Can search devices", false) }, { "Device.ShowAssignmentHistory", new Tuple, Action, string, string, bool>(c => c.Device.ShowAssignmentHistory, (c, v) => c.Device.ShowAssignmentHistory = v, "Show Assignment History", "Can show the assignment history for devices", false) }, { "Device.ShowAttachments", new Tuple, Action, string, string, bool>(c => c.Device.ShowAttachments, (c, v) => c.Device.ShowAttachments = v, "Show Attachments", "Can show device attachments", false) }, { "Device.ShowCertificates", new Tuple, Action, string, string, bool>(c => c.Device.ShowCertificates, (c, v) => c.Device.ShowCertificates = v, "Show Certificates", "Can show certificates associated with devices", false) }, + { "Device.ShowComments", new Tuple, Action, string, string, bool>(c => c.Device.ShowComments, (c, v) => c.Device.ShowComments = v, "Show Comments", "Can show device comments", false) }, { "Device.ShowDetails", new Tuple, Action, string, string, bool>(c => c.Device.ShowDetails, (c, v) => c.Device.ShowDetails = v, "Show Details", "Can show details associated with devices", false) }, { "Device.ShowFlagAssignments", new Tuple, Action, string, string, bool>(c => c.Device.ShowFlagAssignments, (c, v) => c.Device.ShowFlagAssignments = v, "Show Device Flag Assignments", "Can show flags associated with devices", false) }, { "Device.Show", new Tuple, Action, string, string, bool>(c => c.Device.Show, (c, v) => c.Device.Show = v, "Show Devices", "Can show devices", false) }, @@ -458,6 +462,7 @@ namespace Disco.Services.Authorization new ClaimNavigatorItem("Device", "Device", "Permissions related to Devices", false, new List() { new ClaimNavigatorItem("Device.Actions", "Actions", "Permissions related to Device Actions", false, new List() { new ClaimNavigatorItem("Device.Actions.AddAttachments", false), + new ClaimNavigatorItem("Device.Actions.AddComments", false), new ClaimNavigatorItem("Device.Actions.AddFlags", false), new ClaimNavigatorItem("Device.Actions.AllowUnauthenticatedEnrol", false), new ClaimNavigatorItem("Device.Actions.AssignUser", false), @@ -470,8 +475,10 @@ namespace Disco.Services.Authorization new ClaimNavigatorItem("Device.Actions.Import", false), new ClaimNavigatorItem("Device.Actions.Recommission", false), new ClaimNavigatorItem("Device.Actions.RemoveAnyAttachments", false), + new ClaimNavigatorItem("Device.Actions.RemoveAnyComments", false), new ClaimNavigatorItem("Device.Actions.RemoveFlags", false), - new ClaimNavigatorItem("Device.Actions.RemoveOwnAttachments", false) + new ClaimNavigatorItem("Device.Actions.RemoveOwnAttachments", false), + new ClaimNavigatorItem("Device.Actions.RemoveOwnComments", false) }), new ClaimNavigatorItem("Device.Properties", "Device Properties", "Permissions related to Device Properties", false, new List() { new ClaimNavigatorItem("Device.Properties.AssetNumber", false), @@ -484,6 +491,7 @@ namespace Disco.Services.Authorization new ClaimNavigatorItem("Device.ShowAssignmentHistory", false), new ClaimNavigatorItem("Device.ShowAttachments", false), new ClaimNavigatorItem("Device.ShowCertificates", false), + new ClaimNavigatorItem("Device.ShowComments", false), new ClaimNavigatorItem("Device.ShowDetails", false), new ClaimNavigatorItem("Device.ShowFlagAssignments", false), new ClaimNavigatorItem("Device.Show", false), @@ -749,6 +757,7 @@ namespace Disco.Services.Authorization c.Device.Properties.DeviceProfile = true; c.Device.Properties.Location = true; c.Device.Actions.AddAttachments = true; + c.Device.Actions.AddComments = true; c.Device.Actions.AddFlags = true; c.Device.Actions.AllowUnauthenticatedEnrol = true; c.Device.Actions.AssignUser = true; @@ -761,12 +770,15 @@ namespace Disco.Services.Authorization c.Device.Actions.Import = true; c.Device.Actions.Recommission = true; c.Device.Actions.RemoveAnyAttachments = true; + c.Device.Actions.RemoveAnyComments = true; c.Device.Actions.RemoveFlags = true; c.Device.Actions.RemoveOwnAttachments = true; + c.Device.Actions.RemoveOwnComments = true; c.Device.Search = true; c.Device.ShowAssignmentHistory = true; c.Device.ShowAttachments = true; c.Device.ShowCertificates = true; + c.Device.ShowComments = true; c.Device.ShowDetails = true; c.Device.ShowFlagAssignments = true; c.Device.Show = true; @@ -1844,6 +1856,11 @@ namespace Disco.Services.Authorization /// public const string AddAttachments = "Device.Actions.AddAttachments"; + /// Add Comments + /// Can add device comments + /// + public const string AddComments = "Device.Actions.AddComments"; + /// Add Device Flags /// Can add device flags /// @@ -1904,6 +1921,11 @@ namespace Disco.Services.Authorization /// public const string RemoveAnyAttachments = "Device.Actions.RemoveAnyAttachments"; + /// Remove Any Comments + /// Can remove any device comments + /// + public const string RemoveAnyComments = "Device.Actions.RemoveAnyComments"; + /// Remove Device Flags /// Can remove device flags /// @@ -1913,6 +1935,11 @@ namespace Disco.Services.Authorization /// Can remove own attachments from devices /// public const string RemoveOwnAttachments = "Device.Actions.RemoveOwnAttachments"; + + /// Remove Own Comments + /// Can remove own device comments + /// + public const string RemoveOwnComments = "Device.Actions.RemoveOwnComments"; } /// Search Devices @@ -1935,6 +1962,11 @@ namespace Disco.Services.Authorization /// public const string ShowCertificates = "Device.ShowCertificates"; + /// Show Comments + /// Can show device comments + /// + public const string ShowComments = "Device.ShowComments"; + /// Show Details /// Can show details associated with devices /// diff --git a/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceActionsClaims.cs b/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceActionsClaims.cs index 33c9995c..30232b0a 100644 --- a/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceActionsClaims.cs +++ b/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceActionsClaims.cs @@ -16,6 +16,13 @@ [ClaimDetails("Delete", "Can delete devices")] public bool Delete { get; set; } + [ClaimDetails("Add Comments", "Can add device comments")] + public bool AddComments { get; set; } + [ClaimDetails("Remove Any Comments", "Can remove any device comments")] + public bool RemoveAnyComments { get; set; } + [ClaimDetails("Remove Own Comments", "Can remove own device comments")] + public bool RemoveOwnComments { get; set; } + [ClaimDetails("Add Attachments", "Can add attachments to devices")] public bool AddAttachments { get; set; } [ClaimDetails("Remove Any Attachments", "Can remove any attachments from devices")] diff --git a/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceClaims.cs b/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceClaims.cs index 192440fa..0ce34646 100644 --- a/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceClaims.cs +++ b/Disco.Services/Authorization/Roles/ClaimGroups/Device/DeviceClaims.cs @@ -17,6 +17,8 @@ [ClaimDetails("Show Details", "Can show details associated with devices")] public bool ShowDetails { get; set; } + [ClaimDetails("Show Comments", "Can show device comments")] + public bool ShowComments { get; set; } [ClaimDetails("Show Attachments", "Can show device attachments")] public bool ShowAttachments { get; set; } [ClaimDetails("Show Certificates", "Can show certificates associated with devices")] diff --git a/Disco.Services/Devices/DeviceUpdatesHub.cs b/Disco.Services/Devices/DeviceUpdatesHub.cs index fccba73c..567ac0e8 100644 --- a/Disco.Services/Devices/DeviceUpdatesHub.cs +++ b/Disco.Services/Devices/DeviceUpdatesHub.cs @@ -1,7 +1,7 @@ -using Disco.Data.Repository; -using Disco.Data.Repository.Monitor; +using Disco.Data.Repository.Monitor; using Disco.Models.Repository; using Disco.Services.Authorization; +using Disco.Services.Users; using Disco.Services.Web.Signalling; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; @@ -12,14 +12,13 @@ using System.Threading.Tasks; namespace Disco.Services.Devices { - [HubName("deviceUpdates"), DiscoHubAuthorizeAll(Claims.Device.Show, Claims.Device.ShowAttachments)] + [HubName("deviceUpdates"), DiscoHubAuthorize(Claims.Device.Show)] public class DeviceUpdatesHub : Hub { - private const string UserPrefix = "Device_"; - public static IHubContext HubContext { get; private set; } + public static IHubContext HubContext { get; } - private static IDisposable RepositoryBeforeSubscription; - private static IDisposable RepositoryAfterSubscription; + private readonly static IDisposable RepositoryBeforeSubscription; + private readonly static IDisposable RepositoryAfterSubscription; static DeviceUpdatesHub() { @@ -27,18 +26,51 @@ namespace Disco.Services.Devices // Subscribe to Repository Monitor for Changes RepositoryBeforeSubscription = RepositoryMonitor.StreamBeforeCommit - .Where(e => e.EntityType == typeof(DeviceAttachment) && e.EventType == RepositoryMonitorEventType.Deleted) - .Subscribe(RepositoryEventBefore); + .Where(e => + e.EventType == RepositoryMonitorEventType.Deleted && ( + e.EntityType == typeof(DeviceComment) || + e.EntityType == typeof(DeviceAttachment) + ) + ).Subscribe(RepositoryEventBefore); RepositoryAfterSubscription = RepositoryMonitor.StreamAfterCommit - .Where(e => e.EntityType == typeof(DeviceAttachment) && e.EventType == RepositoryMonitorEventType.Added) - .Subscribe(RepositoryAfterEvent); + .Where(e => + e.EventType == RepositoryMonitorEventType.Added && ( + e.EntityType == typeof(DeviceComment) || + e.EntityType == typeof(DeviceAttachment) + ) + ).Subscribe(RepositoryAfterEvent); } - private static string GroupName(string DeviceSerialNumber) + private static bool TryAttachmentGroupName(RepositoryMonitorEvent e, out string groupName) { - return UserPrefix + DeviceSerialNumber; + var deviceSerialNumber = e.GetPreviousPropertyValue(nameof(DeviceAttachment.DeviceSerialNumber)); + if (deviceSerialNumber == null) + { + groupName = null; + return false; + } + groupName = AttachmentGroupName(deviceSerialNumber); + return true; } + private static string AttachmentGroupName(string deviceSerialNumber) + => $"Device_Attachment_{deviceSerialNumber.ToLowerInvariant()}"; + + private static bool TryCommentGroupName(RepositoryMonitorEvent e, out string groupName) + { + var deviceSerialNumber = e.GetPreviousPropertyValue(nameof(DeviceComment.DeviceSerialNumber)); + if (deviceSerialNumber == null) + { + groupName = null; + return false; + } + groupName = CommentGroupName(deviceSerialNumber); + return true; + } + + private static string CommentGroupName(string deviceSerialNumber) + => $"Device_Comment_{deviceSerialNumber.ToLowerInvariant()}"; + public override Task OnConnected() { var deviceSerialNumber = Context.QueryString["DeviceSerialNumber"]; @@ -46,7 +78,12 @@ namespace Disco.Services.Devices if (string.IsNullOrWhiteSpace(deviceSerialNumber)) throw new ArgumentNullException("DeviceSerialNumber"); - Groups.Add(Context.ConnectionId, GroupName(deviceSerialNumber)); + var authorization = UserService.GetAuthorization(Context.User.Identity.Name); + + if (authorization.Has(Claims.Device.ShowComments)) + Groups.Add(Context.ConnectionId, CommentGroupName(deviceSerialNumber)); + if (authorization.Has(Claims.Device.ShowAttachments)) + Groups.Add(Context.ConnectionId, AttachmentGroupName(deviceSerialNumber)); return base.OnConnected(); } @@ -55,16 +92,10 @@ namespace Disco.Services.Devices { if (e.EventType == RepositoryMonitorEventType.Deleted) { - if (e.EntityType == typeof(DeviceAttachment)) - { - var repositoryAttachment = (DeviceAttachment)e.Entity; - string attachmentDeviceSerialNumber; - - using (DiscoDataContext Database = new DiscoDataContext()) - attachmentDeviceSerialNumber = Database.DeviceAttachments.Where(a => a.Id == repositoryAttachment.Id).Select(a => a.DeviceSerialNumber).First(); - - HubContext.Clients.Group(GroupName(attachmentDeviceSerialNumber)).removeAttachment(repositoryAttachment.Id); - } + if (e.Entity is DeviceComment comment && TryCommentGroupName(e, out var commentGroupName)) + HubContext.Clients.Group(commentGroupName).commentRemoved(comment.Id); + else if (e.Entity is DeviceAttachment attachment && TryAttachmentGroupName(e, out var attachmentGroupName)) + HubContext.Clients.Group(attachmentGroupName).attachmentRemoved(attachment.Id); } } @@ -72,12 +103,10 @@ namespace Disco.Services.Devices { if (e.EventType == RepositoryMonitorEventType.Added) { - if (e.EntityType == typeof(DeviceAttachment)) - { - var a = (DeviceAttachment)e.Entity; - - HubContext.Clients.Group(GroupName(a.DeviceSerialNumber)).addAttachment(a.Id); - } + if (e.Entity is DeviceComment comment) + HubContext.Clients.Group(CommentGroupName(comment.DeviceSerialNumber)).commentAdded(comment.Id); + else if (e.Entity is DeviceAttachment attachment) + HubContext.Clients.Group(AttachmentGroupName(attachment.DeviceSerialNumber)).attachmentAdded(attachment.Id); } } } diff --git a/Disco.Services/Users/UserUpdatesHub.cs b/Disco.Services/Users/UserUpdatesHub.cs index 22831221..bf68fd7e 100644 --- a/Disco.Services/Users/UserUpdatesHub.cs +++ b/Disco.Services/Users/UserUpdatesHub.cs @@ -14,7 +14,7 @@ namespace Disco.Services.Users [HubName("userUpdates"), DiscoHubAuthorize(Claims.User.Show)] public class UserUpdatesHub : Hub { - public static IHubContext HubContext { get; private set; } + public static IHubContext HubContext { get; } private static readonly IDisposable repositoryBeforeSubscription; private static readonly IDisposable repositoryAfterSubscription; @@ -52,8 +52,8 @@ namespace Disco.Services.Users return true; } - private static string AttachmentGroupName(string UserId) - => $"User_Attachment_{UserId.ToLowerInvariant()}"; + private static string AttachmentGroupName(string userId) + => $"User_Attachment_{userId.ToLowerInvariant()}"; private static bool TryCommentGroupName(RepositoryMonitorEvent e, out string groupName) { @@ -67,8 +67,8 @@ namespace Disco.Services.Users return true; } - private static string CommentGroupName(string UserId) - => $"User_Comment_{UserId.ToLowerInvariant()}"; + private static string CommentGroupName(string userId) + => $"User_Comment_{userId.ToLowerInvariant()}"; public override Task OnConnected() { diff --git a/Disco.Web/Areas/API/Controllers/DeviceController.cs b/Disco.Web/Areas/API/Controllers/DeviceController.cs index c4030c0d..f959fdb0 100644 --- a/Disco.Web/Areas/API/Controllers/DeviceController.cs +++ b/Disco.Web/Areas/API/Controllers/DeviceController.cs @@ -472,7 +472,88 @@ namespace Disco.Web.Areas.API.Controllers return Json(result, JsonRequestBehavior.AllowGet); } - #region Device Attachements + #region Device Comments + + [DiscoAuthorize(Claims.Device.ShowComments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult Comments(string id) + { + if (string.IsNullOrEmpty(id)) + throw new ArgumentNullException(nameof(id)); + + var device = Database.Devices + .Include(d => d.DeviceComments.Select(l => l.TechUser)) + .Where(d => d.SerialNumber == id).FirstOrDefault(); + if (device == null) + return BadRequest("Invalid Device Serial Number"); + + var results = device.DeviceComments.OrderByDescending(c => c.Timestamp).Select(c => Models.Shared.CommentModel.FromEntity(c)).ToList(); + return Json(results); + } + + [DiscoAuthorize(Claims.Device.ShowComments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult Comment(int id) + { + var entity = Database.DeviceComments + .Include(c => c.TechUser) + .FirstOrDefault(c => c.Id == id); + + if (entity == null) + return BadRequest("Invalid Device Comment Id"); + + var comment = Models.Shared.CommentModel.FromEntity(entity); + return Json(comment); + } + + [DiscoAuthorize(Claims.Device.Actions.AddComments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult CommentAdd(string id, string comment = null) + { + if (string.IsNullOrEmpty(id)) + throw new ArgumentNullException(nameof(id)); + + if (string.IsNullOrWhiteSpace(comment)) + return BadRequest("Comment is required"); + + var device = Database.Devices.Find(id); + if (device == null) + return BadRequest("Invalid Device Serial Number"); + + var entity = new DeviceComment() + { + DeviceSerialNumber = device.SerialNumber, + TechUserId = CurrentUser.UserId, + Timestamp = DateTime.Now, + Comments = comment + }; + Database.DeviceComments.Add(entity); + Database.SaveChanges(); + + return Json(entity.Id); + } + + [DiscoAuthorizeAny(Claims.Device.Actions.RemoveAnyComments, Claims.Device.Actions.RemoveOwnComments)] + [HttpPost, ValidateAntiForgeryToken] + public virtual ActionResult CommentRemove(int id) + { + var entity = Database.DeviceComments.Find(id); + if (entity != null) + { + if (entity.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)) + Authorization.RequireAny(Claims.Device.Actions.RemoveAnyComments, Claims.Device.Actions.RemoveOwnComments); + else + Authorization.Require(Claims.Device.Actions.RemoveAnyComments); + + Database.DeviceComments.Remove(entity); + Database.SaveChanges(); + } + // Doesn't Exist/Already Deleted - OK + return Ok(); + } + #endregion + + #region Device Attachments [DiscoAuthorize(Claims.Device.ShowAttachments), OutputCache(Location = System.Web.UI.OutputCacheLocation.Client, Duration = 172800)] public virtual ActionResult AttachmentDownload(int id) diff --git a/Disco.Web/Areas/API/Models/Shared/CommentModel.cs b/Disco.Web/Areas/API/Models/Shared/CommentModel.cs index ee858d8b..5b8bedbf 100644 --- a/Disco.Web/Areas/API/Models/Shared/CommentModel.cs +++ b/Disco.Web/Areas/API/Models/Shared/CommentModel.cs @@ -46,5 +46,19 @@ namespace Disco.Web.Areas.API.Models.Shared }; } + public static CommentModel FromEntity(DeviceComment comment) + { + return new CommentModel + { + Id = comment.Id, + TargetType = AttachmentTypes.Device, + TargetId = comment.DeviceSerialNumber, + AuthorId = comment.TechUserId, + Author = comment.TechUser.ToString(), + Timestamp = comment.Timestamp, + Comments = comment.Comments, + HtmlComments = comment.Comments.ToHtmlComment().ToString() + }; + } } } \ No newline at end of file diff --git a/Disco.Web/ClientSource/Style/Device.css b/Disco.Web/ClientSource/Style/Device.css index 215ee1b0..cc57d9d1 100644 --- a/Disco.Web/ClientSource/Style/Device.css +++ b/Disco.Web/ClientSource/Style/Device.css @@ -206,6 +206,146 @@ border-top: none; background-color: #eee; } +#DeviceDetailTab-CommentsAndJobs { + display: grid; + grid-template-columns: auto; +} +#DeviceDetailTab-CommentsAndJobs.canShowComments.canShowJobs { + grid-template-columns: 375px auto; +} +#DeviceDetailTab-CommentsAndJobs.canShowComments.canShowJobs > #DeviceDetailTab-Comments { + grid-column: 1; +} +#DeviceDetailTab-CommentsAndJobs.canShowComments.canShowJobs > #DeviceDetailTab-JobsContainer { + grid-column: 2; +} +#DeviceDetailTab-CommentsAndJobs.cannotShowComments div.jobTable { + border: 1px solid #ccc; +} +#DeviceDetailTab-CommentsContainer { + max-height: 650px; +} +#DeviceDetailTab-JobsContainer { + max-height: 650px; + overflow: auto; +} +#Comments { + box-sizing: border-box; + height: 100%; + min-height: 373px; + padding-bottom: 51px; + border: 1px solid #ccc; + background-color: #fff; + position: relative; +} +#Comments div.commentInput { + border-top: 1px solid #ccc; + box-sizing: border-box; + width: 100%; + height: 51px; + padding: 5px; + position: absolute; + bottom: 0; + display: grid; + grid-template-columns: auto 40px; +} +#Comments div.commentInput textarea.commentInput { + grid-column: 1; + border: 0; + padding: 0; + margin: 0; + width: 100%; + height: 40px; + min-height: 40px; + overflow: auto; + resize: none; +} +#Comments div.commentInput button { + grid-column: 2; + appearance: none; + font-size: 1.5em; + display: block; + border: 1px solid #fff; + background-color: #fff; +} +#Comments div.commentInput button:not([disabled]):hover, +#Comments div.commentInput button:not([disabled]):focus { + color: #335A87; + background-color: #ededed; + border: 1px solid #ccc; +} +#Comments div.commentInput button[disabled] { + color: rgba(51, 51, 51, 0.2); + cursor: default; +} +#Comments div.commentOutput { + height: 100%; + overflow: auto; + background-color: #fafafa; + color: #000; +} +#Comments div.commentOutput > div { + padding: 3px; + margin: 4px 6px; + border-bottom: 1px solid #ccc; +} +#Comments div.commentOutput > div span.author { + color: #444; + display: block; + font-weight: 600; + font-size: 0.95em; + float: left; +} +#Comments div.commentOutput > div span.timestamp { + display: block; + float: right; + font-size: 0.9em; + font-style: italic; +} +#Comments div.commentOutput > div div.comment { + clear: both; + display: block; + margin-left: 4px; +} +#Comments div.commentOutput > div div.comment p { + line-height: 1.2em; + padding-bottom: 0.2em; +} +#Comments div.commentOutput > div div.comment h1, +#Comments div.commentOutput > div div.comment h2, +#Comments div.commentOutput > div div.comment h3, +#Comments div.commentOutput > div div.comment h4, +#Comments div.commentOutput > div div.comment h5 { + font-family: "Segoe UI", Arial, Verdana, Tahoma, sans-serif; + font-weight: 600; + font-size: 14px; + margin: 2px 0 !important; +} +#Comments div.commentOutput > div div.comment hr { + margin-top: 0.2em; +} +#Comments div.commentOutput > div div.comment code { + font-size: 0.9em; +} +#Comments div.commentOutput > div:hover span.remove { + opacity: 0.5; +} +#Comments div.commentOutput > div span.remove { + font-size: 1.2em; + color: #e51400; + margin-left: 6px; + cursor: pointer; + opacity: 0; +} +#Comments div.commentOutput > div span.remove:hover { + opacity: 1; +} +#Comments div.commentOutput > div:last-child { + border-bottom: none; +} +#Comments.cannotAddComments { + padding-bottom: 0; +} #Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list, #Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list { max-height: 300px; @@ -230,8 +370,10 @@ padding-top: 0.5em; } #DeviceDetailTab-JobsContainer div.jobTable { - margin: -1px; - border: 1px solid #ddd; + min-height: 320px; + border-top: 1px solid #ccc; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; } #DeviceDetailTab-JobsContainer .dataTables_wrapper .dataTables_filter { margin-top: -24px; diff --git a/Disco.Web/ClientSource/Style/Device.less b/Disco.Web/ClientSource/Style/Device.less index f7e67115..73ae6280 100644 --- a/Disco.Web/ClientSource/Style/Device.less +++ b/Disco.Web/ClientSource/Style/Device.less @@ -179,6 +179,172 @@ } } +#DeviceDetailTab-CommentsAndJobs { + display: grid; + grid-template-columns: auto; + + &.canShowComments.canShowJobs { + grid-template-columns: 375px auto; + + & > #DeviceDetailTab-Comments { + grid-column: 1; + } + + & > #DeviceDetailTab-JobsContainer { + grid-column: 2; + } + } + + &.cannotShowComments div.jobTable { + border: 1px solid @SubtleBorderColour; + } +} + +#DeviceDetailTab-CommentsContainer { + max-height: 650px; +} + +#DeviceDetailTab-JobsContainer { + max-height: 650px; + overflow: auto; +} + +#Comments { + box-sizing: border-box; + height: 100%; + min-height: 373px; + padding-bottom: 51px; + border: 1px solid @SubtleBorderColour; + background-color: @white; + position: relative; + + div.commentInput { + border-top: 1px solid @SubtleBorderColour; + box-sizing: border-box; + width: 100%; + height: 51px; + padding: 5px; + position: absolute; + bottom: 0; + display: grid; + grid-template-columns: auto 40px; + + textarea.commentInput { + grid-column: 1; + border: 0; + padding: 0; + margin: 0; + width: 100%; + height: 40px; + min-height: 40px; + overflow: auto; + resize: none; + } + + button { + grid-column: 2; + appearance: none; + font-size: 1.5em; + display: block; + border: 1px solid @white; + background-color: @white; + + &:not([disabled]) { + &:hover, &:focus { + color: @HyperLinkColour; + background-color: @SubtleColour; + border: 1px solid @SubtleBorderColour; + } + } + + &[disabled] { + color: fade(@HeaderBackgroundColour, 20%); + cursor: default; + } + } + } + + div.commentOutput { + height: 100%; + overflow: auto; + background-color: @BackgroundColourLight; + color: @black; + + & > div { + padding: 3px; + margin: 4px 6px; + border-bottom: 1px solid @SubtleBorderColour; + + span.author { + color: #444; + display: block; + font-weight: @FontWeightBodyBold; + font-size: 0.95em; + float: left; + } + + span.timestamp { + display: block; + float: right; + font-size: 0.90em; + font-style: italic; + } + + div.comment { + clear: both; + display: block; + margin-left: 4px; + + p { + line-height: 1.2em; + padding-bottom: .2em; + } + + h1, h2, h3, h4, h5 { + font-family: @FontFamilyBody; + font-weight: 600; + font-size: 14px; + margin: 2px 0 !important; + } + + hr { + margin-top: .2em; + } + + code { + font-size: .9em; + } + } + + &:hover { + span.remove { + opacity: .5; + } + } + + span.remove { + font-size: 1.2em; + color: @StatusRemove; + margin-left: 6px; + cursor: pointer; + opacity: 0; + + &:hover { + opacity: 1; + } + } + + &:last-child { + border-bottom: none; + } + } + } + + &.cannotAddComments { + padding-bottom: 0; + } +} + #Device_Show_Policies_Profile_Actions_Update_Dialog, #Device_Show_Policies_Batch_Actions_Update_Dialog { .profile-list { max-height: 300px; @@ -206,8 +372,10 @@ #DeviceDetailTab-JobsContainer { div.jobTable { - margin: -1px; - border: 1px solid #ddd; + min-height: 320px; + border-top: 1px solid @SubtleBorderColour; + border-right: 1px solid @SubtleBorderColour; + border-bottom: 1px solid @SubtleBorderColour; } .dataTables_wrapper { diff --git a/Disco.Web/ClientSource/Style/Device.min.css b/Disco.Web/ClientSource/Style/Device.min.css index f49f29fd..3a65469a 100644 --- a/Disco.Web/ClientSource/Style/Device.min.css +++ b/Disco.Web/ClientSource/Style/Device.min.css @@ -1 +1 @@ -.tableData{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableData>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}.tableData>tbody>tr:nth-child(odd)>td{background-color:hsl(0,0%,98.5%);}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}.tableData>tbody>tr:hover>td{background-color:hsl(0,0%,97.5%);}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#f4f4f4;}.tableDataDark{border:solid 1px #d8d8d8;border-collapse:collapse;}.tableDataDark td{border:solid 1px #d8d8d8;background-color:#fff;}.tableDataDark th{background-color:#eee;border:solid 1px #d8d8d8;}.tableDataContainer{background-color:#fff;}.tableDataVertical{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#f4f4f4;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;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;}#layout_PageHeading #Device_Show_Flags{display:inline-block;float:right;font-size:.6em;}#layout_PageHeading #Device_Show_Flags>i{cursor:default;}#layout_PageHeading #Device_Show_Flags>i>.details{display:none;}#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 #Device_Show_Details table.verticalHeadings>tbody>tr>td:first-child{width:104px;font-weight:600;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_Details_Asset_Name{font-weight:600;}#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_User #Device_Show_User_Photo_Container{float:left;padding-right:2px;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Photo{max-width:48px;height:auto;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Flags{font-size:16px;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Flags>i{cursor:default;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Flags>i>.details{display:none;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_GenerateDocument_Container{padding-top:4px;}#Device_Show #Device_Show_Subjects #Device_Show_Policies table.verticalHeadings>tbody>tr>td:first-child{width:120px;font-weight:600;}#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:0;padding:0;}#DeviceDetailTabs #DeviceDetailTabItems{border-radius:0;border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;border-bottom:0;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:0;background-color:#eee;}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list,#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list{max-height:300px;overflow-y:auto;}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list li,#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list li{background-color:#fff;padding:2px 0 2px 4px;}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list li:nth-child(odd),#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list li:nth-child(odd){background-color:hsl(0,0%,98.5%);}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list li.selected,#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list li.selected{background-color:#cddbec;font-weight:600;}#Device_Show_Policies_Profile_Actions_Update_Dialog .enforce-ou,#Device_Show_Policies_Batch_Actions_Update_Dialog .enforce-ou{padding-top:.5em;}#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 #f4f4f4;border-collapse:collapse;}#DeviceDetailTab-DetailsContainer>table>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}#DeviceDetailTab-DetailsContainer>table>tbody>tr:nth-child(odd)>td{background-color:hsl(0,0%,98.5%);}#DeviceDetailTab-DetailsContainer>table>thead>tr>th,#DeviceDetailTab-DetailsContainer>table>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}#DeviceDetailTab-DetailsContainer>table>tbody>tr:hover>td{background-color:hsl(0,0%,97.5%);}#DeviceDetailTab-DetailsContainer>table>tfoot>tr>th,#DeviceDetailTab-DetailsContainer>table>tfoot>tr>td{background-color:#f4f4f4;}#DeviceDetailTab-DetailsContainer>table>tbody>tr>th{width:150px;}#DeviceDetailTab-DetailsContainer>table>tbody>tr>th,#DeviceDetailTab-DetailsContainer>table>tbody>tr>td.pad{padding:10px 6px;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition{position:relative;height:40px;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition>span{position:absolute;display:block;height:40px;box-sizing:border-box;overflow-x:hidden;overflow-y:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#f4f4f4;padding:2px;line-height:18px;border:1px solid #cacaca;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition>span .details{position:relative;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition>span .freespace{position:absolute;top:0;height:40px;display:block;background-color:#fff;background:repeating-linear-gradient(45deg,#f4f4f4,#f4f4f4 10px,#fff 10px,#fff 20px);}#DeviceDetailTab-DetailsContainer .device_detail_mdm_hardware_data code{word-break:break-all;}#deviceShowResources #AttachmentsContainer{padding:0;}#deviceShowResources #Attachments{position:relative;border:1px solid #ccc;background-color:#fff;}#deviceShowResources #Attachments div.attachmentOutput{position:relative;height:320px;overflow:auto;}#deviceShowResources #Attachments div.attachmentOutput>a{display:block;float:left;height:48px;width:218px;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;white-space:nowrap;text-overflow:ellipsis;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 span.icon img.loading{display:none;}#deviceShowResources #Attachments div.attachmentOutput>a:hover{background-color:#ededed;border:1px solid #ccc;}#deviceShowResources #Attachments div.attachmentOutput>a:hover span.remove{opacity:.5;}#deviceShowResources #Attachments div.attachmentOutput>a span.remove{font-size:1.4em;color:#e51400;margin-left:5px;cursor:pointer;opacity:0;}#deviceShowResources #Attachments div.attachmentOutput>a span.remove:hover{opacity:1;}#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:0 4px 0 0;font-size:1.5em;cursor:pointer;float:right;padding:.5em;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin){color:#333;border:1px solid #fff;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin):hover{color:#335a87;background-color:#ededed;border:1px solid #ccc;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled{color:rgba(51,51,51,.2);cursor:default;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled:hover{color:rgba(51,51,51,.2);background-color:inherit;border:1px solid #fff;}#Device_Show_Details_Actions_AddFlag_Dialog{height:400px;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker{position:absolute;width:250px;height:300px;overflow-y:auto;background-color:#fcfcfc;border:1px solid #ccc;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>input{box-sizing:border-box;width:100%;border:0;border-bottom:1px solid #ddd;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div{background-color:#fff;border-bottom:1px solid #ddd;padding:6px 0 6px 6px;cursor:pointer;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div:hover{background-color:#f4f4f4;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected,#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected:hover{background-color:#eee;}#Device_Show_Details_Actions_AddFlag_Dialog .details{display:none;position:absolute;left:280px;top:1em;}#Device_Show_Details_Actions_AddFlag_Dialog .details h4{margin-bottom:4px;}#Device_Show_Details_Actions_AddFlag_Dialog .details textarea{min-width:280px;height:200px;}#DeviceDetailTab-Flags #deviceFlags{border:solid 1px #d8d8d8;border-collapse:collapse;table-layout:fixed;}#DeviceDetailTab-Flags #deviceFlags td{border:solid 1px #d8d8d8;background-color:#fff;}#DeviceDetailTab-Flags #deviceFlags th{background-color:#eee;border:solid 1px #d8d8d8;}#DeviceDetailTab-Flags #deviceFlags i.fa-edit{position:absolute;top:0;right:0;margin-top:4px;font-size:1.1em;cursor:pointer;display:none;color:#335a87;}#DeviceDetailTab-Flags #deviceFlags i.fa-edit:hover{color:#5e8cc2;}#DeviceDetailTab-Flags #deviceFlags td:hover i.fa-edit{display:inline-block;}#DeviceDetailTab-Flags #deviceFlags th.name{width:200px;}#DeviceDetailTab-Flags #deviceFlags tr.removed td{background-color:#f4f4f4;}#DeviceDetailTab-Flags #deviceFlags td.name{vertical-align:middle;}#DeviceDetailTab-Flags #deviceFlags td.name .fa-stack{line-height:1.6em;}#DeviceDetailTab-Flags #deviceFlags td.added,#DeviceDetailTab-Flags #deviceFlags td.removed{vertical-align:middle;}#DeviceDetailTab-Flags #deviceFlags td.added .expressionResult,#DeviceDetailTab-Flags #deviceFlags td.removed .expressionResult{margin-top:4px;font-style:italic;}#DeviceDetailTab-Flags #deviceFlags td.comments{vertical-align:middle;}#DeviceDetailTab-Flags #deviceFlags td.comments .editable{position:relative;}#DeviceDetailTab-Flags #deviceFlags td.comments .commentsRaw{display:none;}#DeviceDetailTab-Flags #deviceFlags td.removed.na{vertical-align:middle;text-align:center;}#DeviceDetailTab-Flags>.none{text-align:center;padding:30px 0;font-style:italic;background-color:#fff;}#Device_Show_Flags_Actions_EditComments_Dialog h4{margin-bottom:4px;}#Device_Show_Flags_Actions_EditComments_Dialog_Comments{width:280px;}#Devices_Export .Devices_Export_Type_Target{margin-top:10px;display:none;}#Devices_Import #ImportFile{width:96%;margin-bottom:8px;}#Devices_Import #Devices_Import_Documentation{width:700px;margin:20px auto;}#Devices_Import #Devices_Import_Documentation>table>tbody th:first-child{width:220px;}#Devices_Import_Completed_Dialog{padding:50px 0;text-align:center;}#Devices_Import_Completed_Dialog h3{margin-bottom:16px;}#Devices_Import_Completed_Dialog i{margin-right:10px;color:#60a917;}#Devices_Import_Loading_Dialog{padding-top:50px;text-align:center;}#Devices_Import_Loading_Dialog i{margin-right:10px;color:#1e6dab;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer{margin:18px 0;overflow-x:auto;border:1px solid #ccc;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead{white-space:nowrap;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead ul.importHeaderType>li>a>span:not(.ui-menu-icon){padding-right:16px;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead ul.importHeaderType ul{z-index:1000;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead td.headerIgnoreColumn{background-color:#fa6800;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead td:not(.headerIgnoreColumn){background-color:#1e6dab;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>tbody td.headerDeviceSerialNumber{border-top-color:#d1e6f7;border-bottom-color:#d1e6f7;background-color:#e2f0fa;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>tbody td.headerIgnoreColumn{max-width:150px;white-space:nowrap;overflow:hidden;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;color:#ccc;}#Devices_Import_Parsing_Dialog{padding-top:50px;text-align:center;}#Devices_Import_Parsing_Dialog i{margin-right:10px;color:#1e6dab;}#Devices_Import_Review #Devices_Import_Review_Navigation{margin-top:15px;text-align:right;}#Devices_Import_Review #Devices_Import_Review_Navigation ul{display:inline-block;padding:0;border:1px solid #bbb;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li{display:inline-block;padding:3px 10px;margin:0;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionDetached{background-color:#ffd0cc;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionModified{background-color:#e2f0fa;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionAdded{background-color:#e7f9d5;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionUnchanged{background-color:hsl(0,0%,98.5%);}#Devices_Import_Review #Devices_Import_Review_TableContainer{margin:18px 0;overflow-x:auto;border:1px solid #ccc;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>thead{white-space:nowrap;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>thead tr:nth-child(2) th{padding-top:0;font-weight:normal;font-size:.9em;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.action{text-align:center;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionDetached td.action i:before{color:#e51400;content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionDetached td{background-color:#ffe7e5;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionUnchanged td.action i:before{content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionUnchanged td{background-color:hsl(0,0%,98.5%);}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionUnchanged td:nth-child(n+3){color:#ccc;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionModified td.action i:before{color:#1e6dab;content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionModified td{background-color:#f4f9fd;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionAdded td.action i:before{color:#60a917;content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionAdded td{background-color:#e7f9d5;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr:not(.actionUnchanged) td.actionUnchanged:nth-child(n+3):not(.headerDeviceSerialNumber){color:#ccc;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.actionError{color:#e51400;background-color:#fff1ef;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.actionError span.errorMessage{display:none;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.actionModified{background-color:#e2f0fa!important;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerDeviceSerialNumber,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerDeviceDecommissionedDate,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerDeviceDecommissionedReason,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerModelId,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerBatchId,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerProfileId,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerAssignedUserId{white-space:nowrap;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody span.smallMessage{color:inherit;} \ No newline at end of file +.tableData{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableData>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}.tableData>tbody>tr:nth-child(odd)>td{background-color:hsl(0,0%,98.5%);}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}.tableData>tbody>tr:hover>td{background-color:hsl(0,0%,97.5%);}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#f4f4f4;}.tableDataDark{border:solid 1px #d8d8d8;border-collapse:collapse;}.tableDataDark td{border:solid 1px #d8d8d8;background-color:#fff;}.tableDataDark th{background-color:#eee;border:solid 1px #d8d8d8;}.tableDataContainer{background-color:#fff;}.tableDataVertical{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#f4f4f4;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;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;}#layout_PageHeading #Device_Show_Flags{display:inline-block;float:right;font-size:.6em;}#layout_PageHeading #Device_Show_Flags>i{cursor:default;}#layout_PageHeading #Device_Show_Flags>i>.details{display:none;}#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 #Device_Show_Details table.verticalHeadings>tbody>tr>td:first-child{width:104px;font-weight:600;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_Details_Asset_Name{font-weight:600;}#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_User #Device_Show_User_Photo_Container{float:left;padding-right:2px;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Photo{max-width:48px;height:auto;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Flags{font-size:16px;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Flags>i{cursor:default;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_User #Device_Show_User_Flags>i>.details{display:none;}#Device_Show #Device_Show_Subjects #Device_Show_Details #Device_Show_GenerateDocument_Container{padding-top:4px;}#Device_Show #Device_Show_Subjects #Device_Show_Policies table.verticalHeadings>tbody>tr>td:first-child{width:120px;font-weight:600;}#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:0;padding:0;}#DeviceDetailTabs #DeviceDetailTabItems{border-radius:0;border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;border-bottom:0;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:0;background-color:#eee;}#DeviceDetailTab-CommentsAndJobs{display:grid;grid-template-columns:auto;}#DeviceDetailTab-CommentsAndJobs.canShowComments.canShowJobs{grid-template-columns:375px auto;}#DeviceDetailTab-CommentsAndJobs.canShowComments.canShowJobs>#DeviceDetailTab-Comments{grid-column:1;}#DeviceDetailTab-CommentsAndJobs.canShowComments.canShowJobs>#DeviceDetailTab-JobsContainer{grid-column:2;}#DeviceDetailTab-CommentsAndJobs.cannotShowComments div.jobTable{border:1px solid #ccc;}#DeviceDetailTab-CommentsContainer{max-height:650px;}#DeviceDetailTab-JobsContainer{max-height:650px;overflow:auto;}#Comments{box-sizing:border-box;height:100%;min-height:373px;padding-bottom:51px;border:1px solid #ccc;background-color:#fff;position:relative;}#Comments div.commentInput{border-top:1px solid #ccc;box-sizing:border-box;width:100%;height:51px;padding:5px;position:absolute;bottom:0;display:grid;grid-template-columns:auto 40px;}#Comments div.commentInput textarea.commentInput{grid-column:1;border:0;padding:0;margin:0;width:100%;height:40px;min-height:40px;overflow:auto;resize:none;}#Comments div.commentInput button{grid-column:2;appearance:none;font-size:1.5em;display:block;border:1px solid #fff;background-color:#fff;}#Comments div.commentInput button:not([disabled]):hover,#Comments div.commentInput button:not([disabled]):focus{color:#335a87;background-color:#ededed;border:1px solid #ccc;}#Comments div.commentInput button[disabled]{color:rgba(51,51,51,.2);cursor:default;}#Comments div.commentOutput{height:100%;overflow:auto;background-color:#fafafa;color:#000;}#Comments div.commentOutput>div{padding:3px;margin:4px 6px;border-bottom:1px solid #ccc;}#Comments div.commentOutput>div span.author{color:#444;display:block;font-weight:600;font-size:.95em;float:left;}#Comments div.commentOutput>div span.timestamp{display:block;float:right;font-size:.9em;font-style:italic;}#Comments div.commentOutput>div div.comment{clear:both;display:block;margin-left:4px;}#Comments div.commentOutput>div div.comment p{line-height:1.2em;padding-bottom:.2em;}#Comments div.commentOutput>div div.comment h1,#Comments div.commentOutput>div div.comment h2,#Comments div.commentOutput>div div.comment h3,#Comments div.commentOutput>div div.comment h4,#Comments div.commentOutput>div div.comment h5{font-family:"Segoe UI",Arial,Verdana,Tahoma,sans-serif;font-weight:600;font-size:14px;margin:2px 0!important;}#Comments div.commentOutput>div div.comment hr{margin-top:.2em;}#Comments div.commentOutput>div div.comment code{font-size:.9em;}#Comments div.commentOutput>div:hover span.remove{opacity:.5;}#Comments div.commentOutput>div span.remove{font-size:1.2em;color:#e51400;margin-left:6px;cursor:pointer;opacity:0;}#Comments div.commentOutput>div span.remove:hover{opacity:1;}#Comments div.commentOutput>div:last-child{border-bottom:0;}#Comments.cannotAddComments{padding-bottom:0;}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list,#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list{max-height:300px;overflow-y:auto;}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list li,#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list li{background-color:#fff;padding:2px 0 2px 4px;}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list li:nth-child(odd),#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list li:nth-child(odd){background-color:hsl(0,0%,98.5%);}#Device_Show_Policies_Profile_Actions_Update_Dialog .profile-list li.selected,#Device_Show_Policies_Batch_Actions_Update_Dialog .profile-list li.selected{background-color:#cddbec;font-weight:600;}#Device_Show_Policies_Profile_Actions_Update_Dialog .enforce-ou,#Device_Show_Policies_Batch_Actions_Update_Dialog .enforce-ou{padding-top:.5em;}#DeviceDetailTab-JobsContainer div.jobTable{min-height:320px;border-top:1px solid #ccc;border-right:1px solid #ccc;border-bottom:1px solid #ccc;}#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 #f4f4f4;border-collapse:collapse;}#DeviceDetailTab-DetailsContainer>table>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}#DeviceDetailTab-DetailsContainer>table>tbody>tr:nth-child(odd)>td{background-color:hsl(0,0%,98.5%);}#DeviceDetailTab-DetailsContainer>table>thead>tr>th,#DeviceDetailTab-DetailsContainer>table>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}#DeviceDetailTab-DetailsContainer>table>tbody>tr:hover>td{background-color:hsl(0,0%,97.5%);}#DeviceDetailTab-DetailsContainer>table>tfoot>tr>th,#DeviceDetailTab-DetailsContainer>table>tfoot>tr>td{background-color:#f4f4f4;}#DeviceDetailTab-DetailsContainer>table>tbody>tr>th{width:150px;}#DeviceDetailTab-DetailsContainer>table>tbody>tr>th,#DeviceDetailTab-DetailsContainer>table>tbody>tr>td.pad{padding:10px 6px;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition{position:relative;height:40px;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition>span{position:absolute;display:block;height:40px;box-sizing:border-box;overflow-x:hidden;overflow-y:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#f4f4f4;padding:2px;line-height:18px;border:1px solid #cacaca;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition>span .details{position:relative;}#DeviceDetailTab-DetailsContainer .device_detail_disk_drives .partition>span .freespace{position:absolute;top:0;height:40px;display:block;background-color:#fff;background:repeating-linear-gradient(45deg,#f4f4f4,#f4f4f4 10px,#fff 10px,#fff 20px);}#DeviceDetailTab-DetailsContainer .device_detail_mdm_hardware_data code{word-break:break-all;}#deviceShowResources #AttachmentsContainer{padding:0;}#deviceShowResources #Attachments{position:relative;border:1px solid #ccc;background-color:#fff;}#deviceShowResources #Attachments div.attachmentOutput{position:relative;height:320px;overflow:auto;}#deviceShowResources #Attachments div.attachmentOutput>a{display:block;float:left;height:48px;width:218px;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;white-space:nowrap;text-overflow:ellipsis;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 span.icon img.loading{display:none;}#deviceShowResources #Attachments div.attachmentOutput>a:hover{background-color:#ededed;border:1px solid #ccc;}#deviceShowResources #Attachments div.attachmentOutput>a:hover span.remove{opacity:.5;}#deviceShowResources #Attachments div.attachmentOutput>a span.remove{font-size:1.4em;color:#e51400;margin-left:5px;cursor:pointer;opacity:0;}#deviceShowResources #Attachments div.attachmentOutput>a span.remove:hover{opacity:1;}#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:0 4px 0 0;font-size:1.5em;cursor:pointer;float:right;padding:.5em;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin){color:#333;border:1px solid #fff;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin):hover{color:#335a87;background-color:#ededed;border:1px solid #ccc;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled{color:rgba(51,51,51,.2);cursor:default;}#deviceShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled:hover{color:rgba(51,51,51,.2);background-color:inherit;border:1px solid #fff;}#Device_Show_Details_Actions_AddFlag_Dialog{height:400px;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker{position:absolute;width:250px;height:300px;overflow-y:auto;background-color:#fcfcfc;border:1px solid #ccc;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>input{box-sizing:border-box;width:100%;border:0;border-bottom:1px solid #ddd;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div{background-color:#fff;border-bottom:1px solid #ddd;padding:6px 0 6px 6px;cursor:pointer;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div:hover{background-color:#f4f4f4;}#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected,#Device_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected:hover{background-color:#eee;}#Device_Show_Details_Actions_AddFlag_Dialog .details{display:none;position:absolute;left:280px;top:1em;}#Device_Show_Details_Actions_AddFlag_Dialog .details h4{margin-bottom:4px;}#Device_Show_Details_Actions_AddFlag_Dialog .details textarea{min-width:280px;height:200px;}#DeviceDetailTab-Flags #deviceFlags{border:solid 1px #d8d8d8;border-collapse:collapse;table-layout:fixed;}#DeviceDetailTab-Flags #deviceFlags td{border:solid 1px #d8d8d8;background-color:#fff;}#DeviceDetailTab-Flags #deviceFlags th{background-color:#eee;border:solid 1px #d8d8d8;}#DeviceDetailTab-Flags #deviceFlags i.fa-edit{position:absolute;top:0;right:0;margin-top:4px;font-size:1.1em;cursor:pointer;display:none;color:#335a87;}#DeviceDetailTab-Flags #deviceFlags i.fa-edit:hover{color:#5e8cc2;}#DeviceDetailTab-Flags #deviceFlags td:hover i.fa-edit{display:inline-block;}#DeviceDetailTab-Flags #deviceFlags th.name{width:200px;}#DeviceDetailTab-Flags #deviceFlags tr.removed td{background-color:#f4f4f4;}#DeviceDetailTab-Flags #deviceFlags td.name{vertical-align:middle;}#DeviceDetailTab-Flags #deviceFlags td.name .fa-stack{line-height:1.6em;}#DeviceDetailTab-Flags #deviceFlags td.added,#DeviceDetailTab-Flags #deviceFlags td.removed{vertical-align:middle;}#DeviceDetailTab-Flags #deviceFlags td.added .expressionResult,#DeviceDetailTab-Flags #deviceFlags td.removed .expressionResult{margin-top:4px;font-style:italic;}#DeviceDetailTab-Flags #deviceFlags td.comments{vertical-align:middle;}#DeviceDetailTab-Flags #deviceFlags td.comments .editable{position:relative;}#DeviceDetailTab-Flags #deviceFlags td.comments .commentsRaw{display:none;}#DeviceDetailTab-Flags #deviceFlags td.removed.na{vertical-align:middle;text-align:center;}#DeviceDetailTab-Flags>.none{text-align:center;padding:30px 0;font-style:italic;background-color:#fff;}#Device_Show_Flags_Actions_EditComments_Dialog h4{margin-bottom:4px;}#Device_Show_Flags_Actions_EditComments_Dialog_Comments{width:280px;}#Devices_Export .Devices_Export_Type_Target{margin-top:10px;display:none;}#Devices_Import #ImportFile{width:96%;margin-bottom:8px;}#Devices_Import #Devices_Import_Documentation{width:700px;margin:20px auto;}#Devices_Import #Devices_Import_Documentation>table>tbody th:first-child{width:220px;}#Devices_Import_Completed_Dialog{padding:50px 0;text-align:center;}#Devices_Import_Completed_Dialog h3{margin-bottom:16px;}#Devices_Import_Completed_Dialog i{margin-right:10px;color:#60a917;}#Devices_Import_Loading_Dialog{padding-top:50px;text-align:center;}#Devices_Import_Loading_Dialog i{margin-right:10px;color:#1e6dab;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer{margin:18px 0;overflow-x:auto;border:1px solid #ccc;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead{white-space:nowrap;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead ul.importHeaderType>li>a>span:not(.ui-menu-icon){padding-right:16px;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead ul.importHeaderType ul{z-index:1000;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead td.headerIgnoreColumn{background-color:#fa6800;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>thead td:not(.headerIgnoreColumn){background-color:#1e6dab;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>tbody td.headerDeviceSerialNumber{border-top-color:#d1e6f7;border-bottom-color:#d1e6f7;background-color:#e2f0fa;}#Devices_Import_Headers #Devices_Import_Headers_TableContainer table>tbody td.headerIgnoreColumn{max-width:150px;white-space:nowrap;overflow:hidden;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;color:#ccc;}#Devices_Import_Parsing_Dialog{padding-top:50px;text-align:center;}#Devices_Import_Parsing_Dialog i{margin-right:10px;color:#1e6dab;}#Devices_Import_Review #Devices_Import_Review_Navigation{margin-top:15px;text-align:right;}#Devices_Import_Review #Devices_Import_Review_Navigation ul{display:inline-block;padding:0;border:1px solid #bbb;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li{display:inline-block;padding:3px 10px;margin:0;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionDetached{background-color:#ffd0cc;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionModified{background-color:#e2f0fa;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionAdded{background-color:#e7f9d5;}#Devices_Import_Review #Devices_Import_Review_Navigation ul li.actionUnchanged{background-color:hsl(0,0%,98.5%);}#Devices_Import_Review #Devices_Import_Review_TableContainer{margin:18px 0;overflow-x:auto;border:1px solid #ccc;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>thead{white-space:nowrap;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>thead tr:nth-child(2) th{padding-top:0;font-weight:normal;font-size:.9em;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.action{text-align:center;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionDetached td.action i:before{color:#e51400;content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionDetached td{background-color:#ffe7e5;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionUnchanged td.action i:before{content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionUnchanged td{background-color:hsl(0,0%,98.5%);}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionUnchanged td:nth-child(n+3){color:#ccc;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionModified td.action i:before{color:#1e6dab;content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionModified td{background-color:#f4f9fd;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionAdded td.action i:before{color:#60a917;content:"";}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr.actionAdded td{background-color:#e7f9d5;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody tr:not(.actionUnchanged) td.actionUnchanged:nth-child(n+3):not(.headerDeviceSerialNumber){color:#ccc;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.actionError{color:#e51400;background-color:#fff1ef;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.actionError span.errorMessage{display:none;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.actionModified{background-color:#e2f0fa!important;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerDeviceSerialNumber,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerDeviceDecommissionedDate,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerDeviceDecommissionedReason,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerModelId,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerBatchId,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerProfileId,#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody td.headerAssignedUserId{white-space:nowrap;}#Devices_Import_Review #Devices_Import_Review_TableContainer table>tbody span.smallMessage{color:inherit;} \ No newline at end of file diff --git a/Disco.Web/ClientSource/Style/User.css b/Disco.Web/ClientSource/Style/User.css index 6ccf2d97..bd83ec15 100644 --- a/Disco.Web/ClientSource/Style/User.css +++ b/Disco.Web/ClientSource/Style/User.css @@ -219,6 +219,13 @@ #UserDetailTab-CommentsAndJobs.cannotShowComments div.jobTable { border: 1px solid #ccc; } +#UserDetailTab-CommentsContainer { + max-height: 650px; +} +#UserDetailTab-JobsContainer { + max-height: 650px; + overflow: auto; +} #Comments { box-sizing: border-box; height: 100%; diff --git a/Disco.Web/ClientSource/Style/User.less b/Disco.Web/ClientSource/Style/User.less index 05385ae7..129a4a5b 100644 --- a/Disco.Web/ClientSource/Style/User.less +++ b/Disco.Web/ClientSource/Style/User.less @@ -191,6 +191,15 @@ } } +#UserDetailTab-CommentsContainer { + max-height: 650px; +} + +#UserDetailTab-JobsContainer { + max-height: 650px; + overflow: auto; +} + #Comments { box-sizing: border-box; height: 100%; diff --git a/Disco.Web/ClientSource/Style/User.min.css b/Disco.Web/ClientSource/Style/User.min.css index d627515e..9dfa44d8 100644 --- a/Disco.Web/ClientSource/Style/User.min.css +++ b/Disco.Web/ClientSource/Style/User.min.css @@ -1 +1 @@ -.tableData{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableData>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}.tableData>tbody>tr:nth-child(odd)>td{background-color:hsl(0,0%,98.5%);}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}.tableData>tbody>tr:hover>td{background-color:hsl(0,0%,97.5%);}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#f4f4f4;}.tableDataDark{border:solid 1px #d8d8d8;border-collapse:collapse;}.tableDataDark td{border:solid 1px #d8d8d8;background-color:#fff;}.tableDataDark th{background-color:#eee;border:solid 1px #d8d8d8;}.tableDataContainer{background-color:#fff;}.tableDataVertical{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#f4f4f4;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 #User_Show_Flags{display:inline-block;float:right;font-size:.6em;}#layout_PageHeading #User_Show_Flags>i{cursor:default;}#layout_PageHeading #User_Show_Flags>i>.details{display:none;}#User_Show #User_Show_Subjects{table-layout:fixed;}#User_Show #User_Show_Subjects>tbody>tr>td{padding-top:0;height:100%;}#User_Show #User_Show_Subjects>tbody>tr>td>div div.status{margin-top:2px;padding-top:2px;border-top:1px dashed #ddd;}#User_Show #User_Show_Subjects>tbody>tr>td>div input.discreet{margin-left:-2px;}#User_Show #User_Show_Subjects>tbody>tr>td:not(:last-child){border-right:1px dashed #aaa;}#User_Show #User_Show_Subjects #User_Show_Details{width:330px;}#User_Show #User_Show_Subjects #User_Show_Details.hasPhoto{width:450px;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Photo_Container{float:left;padding-right:4px;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Photo{max-height:192px;width:auto;}#User_Show #User_Show_Subjects #User_Show_Details table.verticalHeadings{width:auto;}#User_Show #User_Show_Subjects #User_Show_Details table.verticalHeadings>tbody>tr>td:first-child{width:104px;font-weight:600;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Identity_Id{font-weight:600;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_GenerateDocument_Container{padding-top:4px;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Actions{margin-top:4px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment{border-bottom:1px dashed #ddd;padding:4px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment td:first-child{width:90px;font-weight:600;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment img.User_Show_AssignedDevices_CurrentAssignment_Image{float:left;width:64px;height:64px;margin-right:6px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment div.User_Show_AssignedDevices_CurrentAssignment_Details{float:left;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment .User_Show_Assigned_Devices_CurrentAssignment_Flags{font-size:16px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment .User_Show_Assigned_Devices_CurrentAssignment_Flags>i{cursor:default;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment .User_Show_Assigned_Devices_CurrentAssignment_Flags>i>.details{display:none;}#User_Show #User_Show_Subjects #User_Show_Subjects_Actions>td{padding-top:4px;}#UserDetailTabs{margin-top:10px;border-radius:0;background-image:none;background-color:#fff;border:0;padding:0;}#UserDetailTabs #UserDetailTabItems{border-radius:0;border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;border-bottom:0;padding:2px 0 0 4px;background-image:none;background-color:#eee;display:table;}#UserDetailTabs #UserDetailTabItems>li{top:0;border-radius:0;margin:0 5px 0 0;padding:0;line-height:normal;margin-right:4px;}#UserDetailTabs #UserDetailTabItems>li>a{padding:5px 8px;}#UserDetailTabs 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:0;background-color:#eee;}#UserDetailTab-CommentsAndJobs{display:grid;grid-template-columns:auto;}#UserDetailTab-CommentsAndJobs.canShowComments.canShowJobs{grid-template-columns:375px auto;}#UserDetailTab-CommentsAndJobs.canShowComments.canShowJobs>#UserDetailTab-Comments{grid-column:1;}#UserDetailTab-CommentsAndJobs.canShowComments.canShowJobs>#UserDetailTab-JobsContainer{grid-column:2;}#UserDetailTab-CommentsAndJobs.cannotShowComments div.jobTable{border:1px solid #ccc;}#Comments{box-sizing:border-box;height:100%;min-height:373px;padding-bottom:51px;border:1px solid #ccc;background-color:#fff;position:relative;}#Comments div.commentInput{border-top:1px solid #ccc;box-sizing:border-box;width:100%;height:51px;padding:5px;position:absolute;bottom:0;display:grid;grid-template-columns:auto 40px;}#Comments div.commentInput textarea.commentInput{grid-column:1;border:0;padding:0;margin:0;width:100%;height:40px;min-height:40px;overflow:auto;resize:none;}#Comments div.commentInput button{grid-column:2;appearance:none;font-size:1.5em;display:block;border:1px solid #fff;background-color:#fff;}#Comments div.commentInput button:not([disabled]):hover,#Comments div.commentInput button:not([disabled]):focus{color:#335a87;background-color:#ededed;border:1px solid #ccc;}#Comments div.commentInput button[disabled]{color:rgba(51,51,51,.2);cursor:default;}#Comments div.commentOutput{height:100%;overflow:auto;background-color:#fafafa;color:#000;}#Comments div.commentOutput>div{padding:3px;margin:4px 6px;border-bottom:1px solid #ccc;}#Comments div.commentOutput>div span.author{color:#444;display:block;font-weight:600;font-size:.95em;float:left;}#Comments div.commentOutput>div span.timestamp{display:block;float:right;font-size:.9em;font-style:italic;}#Comments div.commentOutput>div div.comment{clear:both;display:block;margin-left:4px;}#Comments div.commentOutput>div div.comment p{line-height:1.2em;padding-bottom:.2em;}#Comments div.commentOutput>div div.comment h1,#Comments div.commentOutput>div div.comment h2,#Comments div.commentOutput>div div.comment h3,#Comments div.commentOutput>div div.comment h4,#Comments div.commentOutput>div div.comment h5{font-family:"Segoe UI",Arial,Verdana,Tahoma,sans-serif;font-weight:600;font-size:14px;margin:2px 0!important;}#Comments div.commentOutput>div div.comment hr{margin-top:.2em;}#Comments div.commentOutput>div div.comment code{font-size:.9em;}#Comments div.commentOutput>div:hover span.remove{opacity:.5;}#Comments div.commentOutput>div span.remove{font-size:1.2em;color:#e51400;margin-left:6px;cursor:pointer;opacity:0;}#Comments div.commentOutput>div span.remove:hover{opacity:1;}#Comments div.commentOutput>div:last-child{border-bottom:0;}#Comments.cannotAddComments{padding-bottom:0;}#UserDetailTab-JobsContainer div.jobTable{min-height:320px;border-top:1px solid #ccc;border-right:1px solid #ccc;border-bottom:1px solid #ccc;}#UserDetailTab-JobsContainer .dataTables_wrapper .dataTables_filter{margin-top:-24px;-moz-opacity:1;opacity:1;}#UserDetailTab-JobsContainer .dataTables_wrapper .dataTables_length{margin-top:-24px;-moz-opacity:1;opacity:1;}#UserDetailTab-JobsContainer .dataTables_wrapper .dataTables_showStatusClosed{right:220px;margin-top:-24px;}#User_Show_Details_Actions_AddFlag_Dialog{height:400px;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker{position:absolute;width:250px;height:300px;overflow-y:auto;background-color:#fcfcfc;border:1px solid #ccc;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>input{box-sizing:border-box;width:100%;border:0;border-bottom:1px solid #ddd;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div{background-color:#fff;border-bottom:1px solid #ddd;padding:6px 0 6px 6px;cursor:pointer;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div:hover{background-color:#f4f4f4;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected,#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected:hover{background-color:#eee;}#User_Show_Details_Actions_AddFlag_Dialog .details{display:none;position:absolute;left:280px;top:1em;}#User_Show_Details_Actions_AddFlag_Dialog .details h4{margin-bottom:4px;}#User_Show_Details_Actions_AddFlag_Dialog .details textarea{min-width:280px;height:200px;}#UserDetailTab-Flags #userFlags{border:solid 1px #d8d8d8;border-collapse:collapse;table-layout:fixed;}#UserDetailTab-Flags #userFlags td{border:solid 1px #d8d8d8;background-color:#fff;}#UserDetailTab-Flags #userFlags th{background-color:#eee;border:solid 1px #d8d8d8;}#UserDetailTab-Flags #userFlags i.fa-edit{position:absolute;top:0;right:0;margin-top:4px;font-size:1.1em;cursor:pointer;display:none;color:#335a87;}#UserDetailTab-Flags #userFlags i.fa-edit:hover{color:#5e8cc2;}#UserDetailTab-Flags #userFlags td:hover i.fa-edit{display:inline-block;}#UserDetailTab-Flags #userFlags th.name{width:200px;}#UserDetailTab-Flags #userFlags tr.removed td{background-color:#f4f4f4;}#UserDetailTab-Flags #userFlags td.name{vertical-align:middle;}#UserDetailTab-Flags #userFlags td.name .fa-stack{line-height:1.6em;}#UserDetailTab-Flags #userFlags td.added,#UserDetailTab-Flags #userFlags td.removed{vertical-align:middle;}#UserDetailTab-Flags #userFlags td.added .expressionResult,#UserDetailTab-Flags #userFlags td.removed .expressionResult{margin-top:4px;font-style:italic;}#UserDetailTab-Flags #userFlags td.comments{vertical-align:middle;}#UserDetailTab-Flags #userFlags td.comments .editable{position:relative;}#UserDetailTab-Flags #userFlags td.comments .commentsRaw{display:none;}#UserDetailTab-Flags #userFlags td.removed.na{vertical-align:middle;text-align:center;}#UserDetailTab-Flags>.none{text-align:center;padding:30px 0;font-style:italic;background-color:#fff;}#User_Show_Flags_Actions_EditComments_Dialog h4{margin-bottom:4px;}#User_Show_Flags_Actions_EditComments_Dialog_Comments{width:280px;}#UserDetailTab-Authorization #UserDetailTab-AuthorizationContainer{background-color:#fff;border:1px solid #ccc;}#UserDetailTab-Authorization #UserDetailTab-Authorization_ClaimsTree_Container{width:50%;float:left;padding:6px 10px 6px 4px;}#UserDetailTab-Authorization #UserDetailTab-Authorization_ClaimsTree_Container>span.smallMessage:last-child{display:block;text-align:right;}#UserDetailTab-Authorization #UserDetailTab-Authorization_Membership{width:40%;float:right;padding:6px 10px;border-left:1px dashed #ccc;border-bottom:1px dashed #ccc;}#UserDetailTab-Authorization #UserDetailTab-Authorization_Membership #UserDetailTab-Authorization_Membership_Roles{margin-bottom:10px;}#UserDetailTab-Authorization #UserDetailTab-Authorization_Membership #UserDetailTab-Authorization_Membership_Groups_Container>span.smallMessage:last-child{display:block;text-align:right;}#UserDetailTab-Authorization #UserDetailTab-Authorization_NoAccess{width:50%;float:left;padding:6px 10px;}#UserDetailTab-Authorization #UserDetailTab-Authorization_NoAccess h3{margin-bottom:10px;}#userShowResources #AttachmentsContainer{padding:0;}#userShowResources #Attachments{position:relative;border:1px solid #ccc;background-color:#fff;}#userShowResources #Attachments div.attachmentOutput{position:relative;height:320px;overflow:auto;}#userShowResources #Attachments div.attachmentOutput>a{display:block;float:left;height:48px;width:218px;padding:2px;margin:2px;font-size:.9em;border:1px solid #fff;color:#000;text-decoration:none;}#userShowResources #Attachments div.attachmentOutput>a span.comments,#userShowResources #Attachments div.attachmentOutput>a span.author,#userShowResources #Attachments div.attachmentOutput>a span.timestamp{display:block;float:left;width:168px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;height:16px;}#userShowResources #Attachments div.attachmentOutput>a span.author{color:#888;width:150px;}#userShowResources #Attachments div.attachmentOutput>a span.timestamp{color:#888;font-style:italic;}#userShowResources #Attachments div.attachmentOutput>a span.icon{display:block;float:left;height:48px;width:48px;margin-right:2px;}#userShowResources #Attachments div.attachmentOutput>a span.icon img{height:48px;width:48px;}#userShowResources #Attachments div.attachmentOutput>a span.icon img.loading{display:none;}#userShowResources #Attachments div.attachmentOutput>a:hover{background-color:#ededed;border:1px solid #ccc;}#userShowResources #Attachments div.attachmentOutput>a:hover span.remove{opacity:.5;}#userShowResources #Attachments div.attachmentOutput>a span.remove{font-size:1.4em;color:#e51400;margin-left:5px;cursor:pointer;opacity:0;}#userShowResources #Attachments div.attachmentOutput>a span.remove:hover{opacity:1;}#userShowResources #Attachments.cannotAddAttachments div.attachmentOutput{height:162px;}#userShowResources #Attachments div.attachmentInput{border-top:1px solid #ccc;height:40px;background-color:#fff;padding:3px;}#userShowResources #Attachments div.attachmentInput span.action{display:block;margin:0 4px 0 0;font-size:1.5em;cursor:pointer;float:right;padding:.5em;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin){color:#333;border:1px solid #fff;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin):hover{color:#335a87;background-color:#ededed;border:1px solid #ccc;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled{color:rgba(51,51,51,.2);cursor:default;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled:hover{color:rgba(51,51,51,.2);background-color:inherit;border:1px solid #fff;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments{margin-top:6px;background-color:#fff;line-height:1.3;border:1px solid #ddd;max-height:300px;overflow-y:auto;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment{display:block;padding:4px;cursor:pointer;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment:not(:last-child){border-bottom:1px dashed #ddd;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment:hover{background-color:#f4f4f4;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment tr:first-child td{width:68px;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment td:first-child{width:90px;font-weight:600;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment img.CreateJob_Assignment_Image{width:64px;height:64px;} \ No newline at end of file +.tableData{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableData>tbody>tr>td{border:solid 1px #f4f4f4;background-color:#fff;}.tableData>tbody>tr:nth-child(odd)>td{background-color:hsl(0,0%,98.5%);}.tableData>thead>tr>th,.tableData>tbody>tr>th{background-color:#f4f4f4;border:solid 1px #f4f4f4;}.tableData>tbody>tr:hover>td{background-color:hsl(0,0%,97.5%);}.tableData>tfoot>tr>th,.tableData>tfoot>tr>td{background-color:#f4f4f4;}.tableDataDark{border:solid 1px #d8d8d8;border-collapse:collapse;}.tableDataDark td{border:solid 1px #d8d8d8;background-color:#fff;}.tableDataDark th{background-color:#eee;border:solid 1px #d8d8d8;}.tableDataContainer{background-color:#fff;}.tableDataVertical{border:solid 1px #f4f4f4;border-collapse:collapse;}.tableDataVertical>tbody>tr:nth-child(odd){background-color:#f4f4f4;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 #User_Show_Flags{display:inline-block;float:right;font-size:.6em;}#layout_PageHeading #User_Show_Flags>i{cursor:default;}#layout_PageHeading #User_Show_Flags>i>.details{display:none;}#User_Show #User_Show_Subjects{table-layout:fixed;}#User_Show #User_Show_Subjects>tbody>tr>td{padding-top:0;height:100%;}#User_Show #User_Show_Subjects>tbody>tr>td>div div.status{margin-top:2px;padding-top:2px;border-top:1px dashed #ddd;}#User_Show #User_Show_Subjects>tbody>tr>td>div input.discreet{margin-left:-2px;}#User_Show #User_Show_Subjects>tbody>tr>td:not(:last-child){border-right:1px dashed #aaa;}#User_Show #User_Show_Subjects #User_Show_Details{width:330px;}#User_Show #User_Show_Subjects #User_Show_Details.hasPhoto{width:450px;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Photo_Container{float:left;padding-right:4px;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Photo{max-height:192px;width:auto;}#User_Show #User_Show_Subjects #User_Show_Details table.verticalHeadings{width:auto;}#User_Show #User_Show_Subjects #User_Show_Details table.verticalHeadings>tbody>tr>td:first-child{width:104px;font-weight:600;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Identity_Id{font-weight:600;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_GenerateDocument_Container{padding-top:4px;}#User_Show #User_Show_Subjects #User_Show_Details #User_Show_Details_Actions{margin-top:4px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment{border-bottom:1px dashed #ddd;padding:4px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment td:first-child{width:90px;font-weight:600;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment img.User_Show_AssignedDevices_CurrentAssignment_Image{float:left;width:64px;height:64px;margin-right:6px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment div.User_Show_AssignedDevices_CurrentAssignment_Details{float:left;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment .User_Show_Assigned_Devices_CurrentAssignment_Flags{font-size:16px;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment .User_Show_Assigned_Devices_CurrentAssignment_Flags>i{cursor:default;}#User_Show #User_Show_Subjects #User_Show_AssignedDevices .User_Show_AssignedDevices_CurrentAssignment .User_Show_Assigned_Devices_CurrentAssignment_Flags>i>.details{display:none;}#User_Show #User_Show_Subjects #User_Show_Subjects_Actions>td{padding-top:4px;}#UserDetailTabs{margin-top:10px;border-radius:0;background-image:none;background-color:#fff;border:0;padding:0;}#UserDetailTabs #UserDetailTabItems{border-radius:0;border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;border-bottom:0;padding:2px 0 0 4px;background-image:none;background-color:#eee;display:table;}#UserDetailTabs #UserDetailTabItems>li{top:0;border-radius:0;margin:0 5px 0 0;padding:0;line-height:normal;margin-right:4px;}#UserDetailTabs #UserDetailTabItems>li>a{padding:5px 8px;}#UserDetailTabs 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:0;background-color:#eee;}#UserDetailTab-CommentsAndJobs{display:grid;grid-template-columns:auto;}#UserDetailTab-CommentsAndJobs.canShowComments.canShowJobs{grid-template-columns:375px auto;}#UserDetailTab-CommentsAndJobs.canShowComments.canShowJobs>#UserDetailTab-Comments{grid-column:1;}#UserDetailTab-CommentsAndJobs.canShowComments.canShowJobs>#UserDetailTab-JobsContainer{grid-column:2;}#UserDetailTab-CommentsAndJobs.cannotShowComments div.jobTable{border:1px solid #ccc;}#UserDetailTab-CommentsContainer{max-height:650px;}#UserDetailTab-JobsContainer{max-height:650px;overflow:auto;}#Comments{box-sizing:border-box;height:100%;min-height:373px;padding-bottom:51px;border:1px solid #ccc;background-color:#fff;position:relative;}#Comments div.commentInput{border-top:1px solid #ccc;box-sizing:border-box;width:100%;height:51px;padding:5px;position:absolute;bottom:0;display:grid;grid-template-columns:auto 40px;}#Comments div.commentInput textarea.commentInput{grid-column:1;border:0;padding:0;margin:0;width:100%;height:40px;min-height:40px;overflow:auto;resize:none;}#Comments div.commentInput button{grid-column:2;appearance:none;font-size:1.5em;display:block;border:1px solid #fff;background-color:#fff;}#Comments div.commentInput button:not([disabled]):hover,#Comments div.commentInput button:not([disabled]):focus{color:#335a87;background-color:#ededed;border:1px solid #ccc;}#Comments div.commentInput button[disabled]{color:rgba(51,51,51,.2);cursor:default;}#Comments div.commentOutput{height:100%;overflow:auto;background-color:#fafafa;color:#000;}#Comments div.commentOutput>div{padding:3px;margin:4px 6px;border-bottom:1px solid #ccc;}#Comments div.commentOutput>div span.author{color:#444;display:block;font-weight:600;font-size:.95em;float:left;}#Comments div.commentOutput>div span.timestamp{display:block;float:right;font-size:.9em;font-style:italic;}#Comments div.commentOutput>div div.comment{clear:both;display:block;margin-left:4px;}#Comments div.commentOutput>div div.comment p{line-height:1.2em;padding-bottom:.2em;}#Comments div.commentOutput>div div.comment h1,#Comments div.commentOutput>div div.comment h2,#Comments div.commentOutput>div div.comment h3,#Comments div.commentOutput>div div.comment h4,#Comments div.commentOutput>div div.comment h5{font-family:"Segoe UI",Arial,Verdana,Tahoma,sans-serif;font-weight:600;font-size:14px;margin:2px 0!important;}#Comments div.commentOutput>div div.comment hr{margin-top:.2em;}#Comments div.commentOutput>div div.comment code{font-size:.9em;}#Comments div.commentOutput>div:hover span.remove{opacity:.5;}#Comments div.commentOutput>div span.remove{font-size:1.2em;color:#e51400;margin-left:6px;cursor:pointer;opacity:0;}#Comments div.commentOutput>div span.remove:hover{opacity:1;}#Comments div.commentOutput>div:last-child{border-bottom:0;}#Comments.cannotAddComments{padding-bottom:0;}#UserDetailTab-JobsContainer div.jobTable{min-height:320px;border-top:1px solid #ccc;border-right:1px solid #ccc;border-bottom:1px solid #ccc;}#UserDetailTab-JobsContainer .dataTables_wrapper .dataTables_filter{margin-top:-24px;-moz-opacity:1;opacity:1;}#UserDetailTab-JobsContainer .dataTables_wrapper .dataTables_length{margin-top:-24px;-moz-opacity:1;opacity:1;}#UserDetailTab-JobsContainer .dataTables_wrapper .dataTables_showStatusClosed{right:220px;margin-top:-24px;}#User_Show_Details_Actions_AddFlag_Dialog{height:400px;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker{position:absolute;width:250px;height:300px;overflow-y:auto;background-color:#fcfcfc;border:1px solid #ccc;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>input{box-sizing:border-box;width:100%;border:0;border-bottom:1px solid #ddd;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div{background-color:#fff;border-bottom:1px solid #ddd;padding:6px 0 6px 6px;cursor:pointer;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div:hover{background-color:#f4f4f4;}#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected,#User_Show_Details_Actions_AddFlag_Dialog .flagPicker>div.selected:hover{background-color:#eee;}#User_Show_Details_Actions_AddFlag_Dialog .details{display:none;position:absolute;left:280px;top:1em;}#User_Show_Details_Actions_AddFlag_Dialog .details h4{margin-bottom:4px;}#User_Show_Details_Actions_AddFlag_Dialog .details textarea{min-width:280px;height:200px;}#UserDetailTab-Flags #userFlags{border:solid 1px #d8d8d8;border-collapse:collapse;table-layout:fixed;}#UserDetailTab-Flags #userFlags td{border:solid 1px #d8d8d8;background-color:#fff;}#UserDetailTab-Flags #userFlags th{background-color:#eee;border:solid 1px #d8d8d8;}#UserDetailTab-Flags #userFlags i.fa-edit{position:absolute;top:0;right:0;margin-top:4px;font-size:1.1em;cursor:pointer;display:none;color:#335a87;}#UserDetailTab-Flags #userFlags i.fa-edit:hover{color:#5e8cc2;}#UserDetailTab-Flags #userFlags td:hover i.fa-edit{display:inline-block;}#UserDetailTab-Flags #userFlags th.name{width:200px;}#UserDetailTab-Flags #userFlags tr.removed td{background-color:#f4f4f4;}#UserDetailTab-Flags #userFlags td.name{vertical-align:middle;}#UserDetailTab-Flags #userFlags td.name .fa-stack{line-height:1.6em;}#UserDetailTab-Flags #userFlags td.added,#UserDetailTab-Flags #userFlags td.removed{vertical-align:middle;}#UserDetailTab-Flags #userFlags td.added .expressionResult,#UserDetailTab-Flags #userFlags td.removed .expressionResult{margin-top:4px;font-style:italic;}#UserDetailTab-Flags #userFlags td.comments{vertical-align:middle;}#UserDetailTab-Flags #userFlags td.comments .editable{position:relative;}#UserDetailTab-Flags #userFlags td.comments .commentsRaw{display:none;}#UserDetailTab-Flags #userFlags td.removed.na{vertical-align:middle;text-align:center;}#UserDetailTab-Flags>.none{text-align:center;padding:30px 0;font-style:italic;background-color:#fff;}#User_Show_Flags_Actions_EditComments_Dialog h4{margin-bottom:4px;}#User_Show_Flags_Actions_EditComments_Dialog_Comments{width:280px;}#UserDetailTab-Authorization #UserDetailTab-AuthorizationContainer{background-color:#fff;border:1px solid #ccc;}#UserDetailTab-Authorization #UserDetailTab-Authorization_ClaimsTree_Container{width:50%;float:left;padding:6px 10px 6px 4px;}#UserDetailTab-Authorization #UserDetailTab-Authorization_ClaimsTree_Container>span.smallMessage:last-child{display:block;text-align:right;}#UserDetailTab-Authorization #UserDetailTab-Authorization_Membership{width:40%;float:right;padding:6px 10px;border-left:1px dashed #ccc;border-bottom:1px dashed #ccc;}#UserDetailTab-Authorization #UserDetailTab-Authorization_Membership #UserDetailTab-Authorization_Membership_Roles{margin-bottom:10px;}#UserDetailTab-Authorization #UserDetailTab-Authorization_Membership #UserDetailTab-Authorization_Membership_Groups_Container>span.smallMessage:last-child{display:block;text-align:right;}#UserDetailTab-Authorization #UserDetailTab-Authorization_NoAccess{width:50%;float:left;padding:6px 10px;}#UserDetailTab-Authorization #UserDetailTab-Authorization_NoAccess h3{margin-bottom:10px;}#userShowResources #AttachmentsContainer{padding:0;}#userShowResources #Attachments{position:relative;border:1px solid #ccc;background-color:#fff;}#userShowResources #Attachments div.attachmentOutput{position:relative;height:320px;overflow:auto;}#userShowResources #Attachments div.attachmentOutput>a{display:block;float:left;height:48px;width:218px;padding:2px;margin:2px;font-size:.9em;border:1px solid #fff;color:#000;text-decoration:none;}#userShowResources #Attachments div.attachmentOutput>a span.comments,#userShowResources #Attachments div.attachmentOutput>a span.author,#userShowResources #Attachments div.attachmentOutput>a span.timestamp{display:block;float:left;width:168px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;height:16px;}#userShowResources #Attachments div.attachmentOutput>a span.author{color:#888;width:150px;}#userShowResources #Attachments div.attachmentOutput>a span.timestamp{color:#888;font-style:italic;}#userShowResources #Attachments div.attachmentOutput>a span.icon{display:block;float:left;height:48px;width:48px;margin-right:2px;}#userShowResources #Attachments div.attachmentOutput>a span.icon img{height:48px;width:48px;}#userShowResources #Attachments div.attachmentOutput>a span.icon img.loading{display:none;}#userShowResources #Attachments div.attachmentOutput>a:hover{background-color:#ededed;border:1px solid #ccc;}#userShowResources #Attachments div.attachmentOutput>a:hover span.remove{opacity:.5;}#userShowResources #Attachments div.attachmentOutput>a span.remove{font-size:1.4em;color:#e51400;margin-left:5px;cursor:pointer;opacity:0;}#userShowResources #Attachments div.attachmentOutput>a span.remove:hover{opacity:1;}#userShowResources #Attachments.cannotAddAttachments div.attachmentOutput{height:162px;}#userShowResources #Attachments div.attachmentInput{border-top:1px solid #ccc;height:40px;background-color:#fff;padding:3px;}#userShowResources #Attachments div.attachmentInput span.action{display:block;margin:0 4px 0 0;font-size:1.5em;cursor:pointer;float:right;padding:.5em;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin){color:#333;border:1px solid #fff;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin):hover{color:#335a87;background-color:#ededed;border:1px solid #ccc;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled{color:rgba(51,51,51,.2);cursor:default;}#userShowResources #Attachments div.attachmentInput span.action:not(.fa-spin).disabled:hover{color:rgba(51,51,51,.2);background-color:inherit;border:1px solid #fff;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments{margin-top:6px;background-color:#fff;line-height:1.3;border:1px solid #ddd;max-height:300px;overflow-y:auto;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment{display:block;padding:4px;cursor:pointer;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment:not(:last-child){border-bottom:1px dashed #ddd;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment:hover{background-color:#f4f4f4;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment tr:first-child td{width:68px;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment td:first-child{width:90px;font-weight:600;}#User_Show_Details_Actions_CreateJob_Dialog #CreateJob_Assignments li.CreateJob_Assignment img.CreateJob_Assignment_Image{width:64px;height:64px;} \ No newline at end of file diff --git a/Disco.Web/Disco.Web.csproj b/Disco.Web/Disco.Web.csproj index 69d601ed..c9df72a3 100644 --- a/Disco.Web/Disco.Web.csproj +++ b/Disco.Web/Disco.Web.csproj @@ -909,6 +909,16 @@ + + _Comments.cshtml + True + True + + + _CommentsAndJobs.cshtml + True + True + _Flags.cshtml True @@ -1071,11 +1081,6 @@ True _Certificates.cshtml - - True - True - _Jobs.cshtml - _Resources.cshtml True @@ -1336,8 +1341,8 @@ True True - - Comments.cshtml + + _Comments.cshtml True True @@ -2099,6 +2104,14 @@ RazorGenerator AddOffline.generated.cs + + RazorGenerator + _Comments.generated.cs + + + RazorGenerator + _CommentsAndJobs.generated.cs + RazorGenerator _Flags.generated.cs @@ -2119,10 +2132,6 @@ RazorGenerator _Certificates.generated.cs - - RazorGenerator - _Jobs.generated.cs - RazorGenerator _Resources.generated.cs @@ -2575,9 +2584,9 @@ RazorGenerator _CommentsAndJobs.generated.cs - + RazorGenerator - Comments.generated.cs + _Comments.generated.cs RazorGenerator diff --git a/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs b/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs index 0c5a54e5..b7842977 100644 --- a/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs +++ b/Disco.Web/Extensions/T4MVC/API.DeviceController.generated.cs @@ -157,6 +157,30 @@ namespace Disco.Web.Areas.API.Controllers } [NonAction] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public virtual System.Web.Mvc.ActionResult Comments() + { + return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Comments); + } + [NonAction] + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public virtual System.Web.Mvc.ActionResult Comment() + { + return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Comment); + } + [NonAction] + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public virtual System.Web.Mvc.ActionResult CommentAdd() + { + return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.CommentAdd); + } + [NonAction] + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public virtual System.Web.Mvc.ActionResult CommentRemove() + { + return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.CommentRemove); + } + [NonAction] + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public virtual System.Web.Mvc.ActionResult AttachmentDownload() { return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.AttachmentDownload); @@ -284,6 +308,10 @@ namespace Disco.Web.Areas.API.Controllers public readonly string GeneratePdf = "GeneratePdf"; public readonly string GeneratePdfPackage = "GeneratePdfPackage"; public readonly string LastNetworkLogonDate = "LastNetworkLogonDate"; + public readonly string Comments = "Comments"; + public readonly string Comment = "Comment"; + public readonly string CommentAdd = "CommentAdd"; + public readonly string CommentRemove = "CommentRemove"; public readonly string AttachmentDownload = "AttachmentDownload"; public readonly string AttachmentThumbnail = "AttachmentThumbnail"; public readonly string AttachmentUpload = "AttachmentUpload"; @@ -322,6 +350,10 @@ namespace Disco.Web.Areas.API.Controllers public const string GeneratePdf = "GeneratePdf"; public const string GeneratePdfPackage = "GeneratePdfPackage"; public const string LastNetworkLogonDate = "LastNetworkLogonDate"; + public const string Comments = "Comments"; + public const string Comment = "Comment"; + public const string CommentAdd = "CommentAdd"; + public const string CommentRemove = "CommentRemove"; public const string AttachmentDownload = "AttachmentDownload"; public const string AttachmentThumbnail = "AttachmentThumbnail"; public const string AttachmentUpload = "AttachmentUpload"; @@ -498,6 +530,39 @@ namespace Disco.Web.Areas.API.Controllers { public readonly string id = "id"; } + static readonly ActionParamsClass_Comments s_params_Comments = new ActionParamsClass_Comments(); + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public ActionParamsClass_Comments CommentsParams { get { return s_params_Comments; } } + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public class ActionParamsClass_Comments + { + public readonly string id = "id"; + } + static readonly ActionParamsClass_Comment s_params_Comment = new ActionParamsClass_Comment(); + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public ActionParamsClass_Comment CommentParams { get { return s_params_Comment; } } + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public class ActionParamsClass_Comment + { + public readonly string id = "id"; + } + static readonly ActionParamsClass_CommentAdd s_params_CommentAdd = new ActionParamsClass_CommentAdd(); + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public ActionParamsClass_CommentAdd CommentAddParams { get { return s_params_CommentAdd; } } + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public class ActionParamsClass_CommentAdd + { + public readonly string id = "id"; + public readonly string comment = "comment"; + } + static readonly ActionParamsClass_CommentRemove s_params_CommentRemove = new ActionParamsClass_CommentRemove(); + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public ActionParamsClass_CommentRemove CommentRemoveParams { get { return s_params_CommentRemove; } } + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public class ActionParamsClass_CommentRemove + { + public readonly string id = "id"; + } static readonly ActionParamsClass_AttachmentDownload s_params_AttachmentDownload = new ActionParamsClass_AttachmentDownload(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public ActionParamsClass_AttachmentDownload AttachmentDownloadParams { get { return s_params_AttachmentDownload; } } @@ -874,6 +939,55 @@ namespace Disco.Web.Areas.API.Controllers return callInfo; } + [NonAction] + partial void CommentsOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id); + + [NonAction] + public override System.Web.Mvc.ActionResult Comments(string id) + { + var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Comments); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); + CommentsOverride(callInfo, id); + return callInfo; + } + + [NonAction] + partial void CommentOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id); + + [NonAction] + public override System.Web.Mvc.ActionResult Comment(int id) + { + var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Comment); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); + CommentOverride(callInfo, id); + return callInfo; + } + + [NonAction] + partial void CommentAddOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id, string comment); + + [NonAction] + public override System.Web.Mvc.ActionResult CommentAdd(string id, string comment) + { + var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.CommentAdd); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "comment", comment); + CommentAddOverride(callInfo, id, comment); + return callInfo; + } + + [NonAction] + partial void CommentRemoveOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id); + + [NonAction] + public override System.Web.Mvc.ActionResult CommentRemove(int id) + { + var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.CommentRemove); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); + CommentRemoveOverride(callInfo, id); + return callInfo; + } + [NonAction] partial void AttachmentDownloadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id); diff --git a/Disco.Web/Extensions/T4MVC/DeviceController.generated.cs b/Disco.Web/Extensions/T4MVC/DeviceController.generated.cs index f8f83bf8..7d7b5a42 100644 --- a/Disco.Web/Extensions/T4MVC/DeviceController.generated.cs +++ b/Disco.Web/Extensions/T4MVC/DeviceController.generated.cs @@ -217,17 +217,19 @@ namespace Disco.Web.Controllers { public readonly string _AssignmentHistory = "_AssignmentHistory"; public readonly string _Certificates = "_Certificates"; + public readonly string _Comments = "_Comments"; + public readonly string _CommentsAndJobs = "_CommentsAndJobs"; public readonly string _Details = "_Details"; public readonly string _Flags = "_Flags"; - 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 _Comments = "~/Views/Device/DeviceParts/_Comments.cshtml"; + public readonly string _CommentsAndJobs = "~/Views/Device/DeviceParts/_CommentsAndJobs.cshtml"; public readonly string _Details = "~/Views/Device/DeviceParts/_Details.cshtml"; public readonly string _Flags = "~/Views/Device/DeviceParts/_Flags.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"; } diff --git a/Disco.Web/Extensions/T4MVC/UserController.generated.cs b/Disco.Web/Extensions/T4MVC/UserController.generated.cs index 98a00b80..b4bbe33f 100644 --- a/Disco.Web/Extensions/T4MVC/UserController.generated.cs +++ b/Disco.Web/Extensions/T4MVC/UserController.generated.cs @@ -132,19 +132,19 @@ namespace Disco.Web.Controllers { public readonly string _AssignmentHistory = "_AssignmentHistory"; public readonly string _Authorization = "_Authorization"; + public readonly string _Comments = "_Comments"; public readonly string _CommentsAndJobs = "_CommentsAndJobs"; public readonly string _Flags = "_Flags"; public readonly string _Resources = "_Resources"; public readonly string _Subject = "_Subject"; - public readonly string Comments = "Comments"; } public readonly string _AssignmentHistory = "~/Views/User/UserParts/_AssignmentHistory.cshtml"; public readonly string _Authorization = "~/Views/User/UserParts/_Authorization.cshtml"; + public readonly string _Comments = "~/Views/User/UserParts/_Comments.cshtml"; public readonly string _CommentsAndJobs = "~/Views/User/UserParts/_CommentsAndJobs.cshtml"; public readonly string _Flags = "~/Views/User/UserParts/_Flags.cshtml"; public readonly string _Resources = "~/Views/User/UserParts/_Resources.cshtml"; public readonly string _Subject = "~/Views/User/UserParts/_Subject.cshtml"; - public readonly string Comments = "~/Views/User/UserParts/Comments.cshtml"; } } } diff --git a/Disco.Web/Views/Device/DeviceParts/_Comments.cshtml b/Disco.Web/Views/Device/DeviceParts/_Comments.cshtml new file mode 100644 index 00000000..1e695e8b --- /dev/null +++ b/Disco.Web/Views/Device/DeviceParts/_Comments.cshtml @@ -0,0 +1,212 @@ +@model Disco.Web.Models.Device.ShowModel +@{ + Authorization.Require(Claims.Device.ShowComments); + var canAddComments = Authorization.Has(Claims.Device.Actions.AddComments); + var canRemoveAnyComments = Authorization.Has(Claims.Device.Actions.RemoveAnyComments); + var canRemoveOwnComments = Authorization.Has(Claims.Device.Actions.RemoveOwnComments); +} +
+ @Html.AntiForgeryToken() + @if (canAddComments) + { +
+ + +
+ } +
+ @foreach (var c in Model.Device.DeviceComments.OrderBy(m => m.Timestamp)) + { +
+ @c.TechUser.ToStringFriendly()@if (canRemoveAnyComments || (canRemoveOwnComments && c.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase))) + {}@c.Timestamp.ToFullDateTime() +
@c.Comments.ToHtmlComment()
+
+ } +
+
+ +@if (canAddComments) +{ + +} +@if (canRemoveAnyComments || canRemoveOwnComments) +{ + +} diff --git a/Disco.Web/Views/Device/DeviceParts/_Comments.generated.cs b/Disco.Web/Views/Device/DeviceParts/_Comments.generated.cs new file mode 100644 index 00000000..6080ce9e --- /dev/null +++ b/Disco.Web/Views/Device/DeviceParts/_Comments.generated.cs @@ -0,0 +1,452 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// 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; + using Disco.Models.Repository; + using Disco.Services; + using Disco.Services.Authorization; + using Disco.Services.Web; + using Disco.Web; + using Disco.Web.Extensions; + + [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")] + [System.Web.WebPages.PageVirtualPathAttribute("~/Views/Device/DeviceParts/_Comments.cshtml")] + public partial class _Comments : Disco.Services.Web.WebViewPage + { + public _Comments() + { + } + public override void Execute() + { + + #line 2 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + + Authorization.Require(Claims.Device.ShowComments); + var canAddComments = Authorization.Has(Claims.Device.Actions.AddComments); + var canRemoveAnyComments = Authorization.Has(Claims.Device.Actions.RemoveAnyComments); + var canRemoveOwnComments = Authorization.Has(Claims.Device.Actions.RemoveOwnComments); + + + #line default + #line hidden +WriteLiteral("\r\n(canAddComments ? "canAddComments" : "cannotAddComments" + + #line default + #line hidden +, 395), false) + + #line 8 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + , Tuple.Create(Tuple.Create(" ", 453), Tuple.Create(canRemoveAnyComments ? "canRemoveAnyComments" : "cannotRemoveAnyComments" + + #line default + #line hidden +, 454), false) + + #line 8 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + , Tuple.Create(Tuple.Create(" ", 530), Tuple.Create(canRemoveOwnComments ? "canRemoveOwnComments" : "cannotRemoveOwnComments" + + #line default + #line hidden +, 531), false) +); + +WriteLiteral(" data-id=\""); + + + #line 8 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + Write(Model.Device.SerialNumber); + + + #line default + #line hidden +WriteLiteral("\""); + +WriteLiteral(" data-userid=\""); + + + #line 8 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + Write(CurrentUser.UserId); + + + #line default + #line hidden +WriteLiteral("\""); + +WriteLiteral(" data-addurl=\""); + + + #line 8 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + Write(Url.Action(MVC.API.Device.CommentAdd(Model.Device.SerialNumber))); + + + #line default + #line hidden +WriteLiteral("\""); + +WriteLiteral(" data-removeurl=\""); + + + #line 8 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + Write(Url.Action(MVC.API.Device.CommentRemove())); + + + #line default + #line hidden +WriteLiteral("\""); + +WriteLiteral(" data-geturl=\""); + + + #line 8 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + Write(Url.Action(MVC.API.Device.Comment())); + + + #line default + #line hidden +WriteLiteral("\""); + +WriteLiteral(">\r\n"); + +WriteLiteral(" "); + + + #line 9 "..\..\Views\Device\DeviceParts\_Comments.cshtml" +Write(Html.AntiForgeryToken()); + + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 10 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + + + #line default + #line hidden + + #line 10 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + if (canAddComments) + { + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n \r\n \r\n"); + + + #line 16 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 18 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + + + #line default + #line hidden + + #line 18 "..\..\Views\Device\DeviceParts\_Comments.cshtml" + foreach (var c in Model.Device.DeviceComments.OrderBy(m => m.Timestamp)) + { + + + #line default + #line hidden +WriteLiteral("