From 7bdbeb6a8231c76c57d6a0688a7b9b7ac53d7047 Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Tue, 11 Feb 2014 16:50:03 +1100 Subject: [PATCH] Feature #35: Livestamp implemented Humanized dates now update automatically when a page is left open for some time. --- Disco.Data/Disco.Data.csproj | 2 +- Disco.Models/Disco.Models.csproj | 3 +- Disco.Models/Repository/Job/JobAssignment.cs | 30 - .../Extensions/DateTimeExtensions.cs | 29 +- Disco.Web/App_Code/CommonHelpers.cshtml | 94 +- Disco.Web/App_Code/CommonHelpers.generated.cs | 952 +++++++++--------- .../Areas/API/Controllers/DeviceController.cs | 2 +- .../Controllers/DocumentTemplateController.cs | 4 +- .../API/Models/Attachment/_AttachmentModel.cs | 24 +- .../ImporterUndetectedFilesModel.cs | 2 +- .../Areas/API/Models/Job/_CommentModel.cs | 24 +- .../Areas/API/Models/Job/_DateChangeModel.cs | 8 +- Disco.Web/ClientSource/Scripts/Core.js | 154 ++- Disco.Web/ClientSource/Scripts/Core.js.bundle | 1 + Disco.Web/ClientSource/Scripts/Core.min.js | 2 +- .../ClientSource/Scripts/Core.min.js.map | 6 +- .../ClientSource/Scripts/Core/_references.js | 1 + .../Core/disco.dataTables.extensions.js | 10 +- .../ClientSource/Scripts/Core/livestamp.js | 143 +++ .../Modules/Disco-PropertyChangeHelpers.js | 12 +- .../Disco-PropertyChangeHelpers.min.js | 6 +- .../Disco-PropertyChangeHelpers.min.js.map | 4 +- .../disco.propertychangehelpers.js | 10 +- Disco.Web/Disco.Web.csproj | 3 +- .../Device/DeviceParts/_Resources.cshtml | 5 +- .../DeviceParts/_Resources.generated.cs | 53 +- .../Views/Device/DeviceParts/_Subject.cshtml | 10 +- .../Device/DeviceParts/_Subject.generated.cs | 366 +++---- Disco.Web/Views/Job/JobParts/Insurance.cshtml | 2 +- .../Views/Job/JobParts/Insurance.generated.cs | 3 +- .../Job/JobParts/NonWarrantyFinance.cshtml | 2 +- .../JobParts/NonWarrantyFinance.generated.cs | 3 +- Disco.Web/Views/Job/JobParts/Repairs.cshtml | 2 +- .../Views/Job/JobParts/Repairs.generated.cs | 3 +- Disco.Web/Views/Job/JobParts/Resources.cshtml | 12 +- .../Views/Job/JobParts/Resources.generated.cs | 229 +++-- Disco.Web/Views/Job/JobParts/_Subject.cshtml | 6 +- .../Views/Job/JobParts/_Subject.generated.cs | 121 ++- .../Views/User/UserParts/_Resources.cshtml | 5 +- .../User/UserParts/_Resources.generated.cs | 69 +- 40 files changed, 1395 insertions(+), 1022 deletions(-) delete mode 100644 Disco.Models/Repository/Job/JobAssignment.cs create mode 100644 Disco.Web/ClientSource/Scripts/Core/livestamp.js diff --git a/Disco.Data/Disco.Data.csproj b/Disco.Data/Disco.Data.csproj index 6b47b0db..19fbae17 100644 --- a/Disco.Data/Disco.Data.csproj +++ b/Disco.Data/Disco.Data.csproj @@ -194,7 +194,7 @@ - + diff --git a/Disco.Models/Disco.Models.csproj b/Disco.Models/Disco.Models.csproj index 17e9cfa2..564094a8 100644 --- a/Disco.Models/Disco.Models.csproj +++ b/Disco.Models/Disco.Models.csproj @@ -88,7 +88,6 @@ - @@ -167,7 +166,7 @@ - + diff --git a/Disco.Models/Repository/Job/JobAssignment.cs b/Disco.Models/Repository/Job/JobAssignment.cs deleted file mode 100644 index d6c2b529..00000000 --- a/Disco.Models/Repository/Job/JobAssignment.cs +++ /dev/null @@ -1,30 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.ComponentModel.DataAnnotations; -//using System.ComponentModel.DataAnnotations.Schema; - -//namespace Disco.Models.Repository -//{ -// // Added 2012-10-23 G# - DBv5 Migration -// public class JobAssignment -// { -// [Key, Required, ColumnAttribute(Order = 0)] -// public int JobId { get; set; } -// [Key, Required, ColumnAttribute(Order = 1)] -// public string TechUserId { get; set; } -// [Key, Required, ColumnAttribute(Order = 2)] -// public DateTime AssignedDate { get; set; } - -// public DateTime? UnassignedDate { get; set; } - -// public DateTime? TargetCompletionDate { get; set; } - -// [ForeignKey("JobId"), InverseProperty("JobAssignments")] -// public virtual Job Job { get; set; } - -// [ForeignKey("TechUserId")] -// public User TechUser { get; set; } -// } -//} diff --git a/Disco.Services/Extensions/DateTimeExtensions.cs b/Disco.Services/Extensions/DateTimeExtensions.cs index d951ac59..485e9d2c 100644 --- a/Disco.Services/Extensions/DateTimeExtensions.cs +++ b/Disco.Services/Extensions/DateTimeExtensions.cs @@ -8,7 +8,6 @@ namespace Disco { public static class DateTimeExtensions { - public static string From(this DateTime moment, DateTime to, bool withoutSuffix) { var duration = to - moment; @@ -62,7 +61,6 @@ namespace Disco { return moment.FromNow("n/a"); } - public static string Humanize(this TimeSpan duration, bool withSuffix) { string output = RelativeTime(duration.Ticks > 0 ? duration : duration.Negate(), true); @@ -123,25 +121,30 @@ namespace Disco else return NullValue; } - public static long ToSortable(this DateTime? d) + + private const long unixEpocOffset = 621355968000000000; + public static long ToUnixEpoc(this DateTime d) + { + var epoc = new DateTime(unixEpocOffset, DateTimeKind.Utc); + var offset = d.ToUniversalTime() - epoc; + return offset.Ticks / 10000; + } + public static long? ToUnixEpoc(this DateTime? d) { if (d.HasValue) - return d.Value.ToBinary(); + return d.Value.ToUnixEpoc(); else - return -1; + return null; } - public static long ToSortable(this DateTime d) + + public static string ToISO8601(this DateTime d) { - return d.ToBinary(); + return d.ToString("yyyy-MM-ddTHH\\:mm\\:sszzz"); } - public static string ToJavaScript(this DateTime d) - { - return d.ToString("yyyy/MM/dd hh:mm tt"); - } - public static string ToJavaScript(this DateTime? d) + public static string ToISO8601(this DateTime? d) { if (d.HasValue) - return d.Value.ToString("yyyy/MM/dd hh:mm tt"); + return d.Value.ToISO8601(); else return null; } diff --git a/Disco.Web/App_Code/CommonHelpers.cshtml b/Disco.Web/App_Code/CommonHelpers.cshtml index fda72764..2c0d3189 100644 --- a/Disco.Web/App_Code/CommonHelpers.cshtml +++ b/Disco.Web/App_Code/CommonHelpers.cshtml @@ -6,10 +6,43 @@ @using System.Web.Mvc @using System.Web.Mvc.Html; @using Disco.Services.Web; + + @helper FriendlyDate(DateTime d, string ElementId = null, bool WithoutSuffix = false) -{@d.FromNow(WithoutSuffix)} +{@d.ToFullDateTime()} @helper FriendlyDate(DateTime? d, string NullValue = "n/a", string ElementId = null, bool WithoutSuffix = false) -{@d.FromNow(WithoutSuffix, NullValue)} +{@d.ToFullDateTime(NullValue)} +@helper FriendlyDateAndUser(DateTime? d, User u, string DateNullValue = "n/a", bool WithoutSuffix = false) +{ + @FriendlyDate(d, DateNullValue, WithoutSuffix: WithoutSuffix); + @FriendlyUser(u, null, " by"); +} +@helper FriendlyDateAndUser(DateTime d, User u, bool WithoutSuffix = false) +{ + @FriendlyDate(d, WithoutSuffix: WithoutSuffix); + @FriendlyUser(u, null, " by"); +} +@helper FriendlyDateAndTitleUser(DateTime? d, User u, string DateNullValue = "n/a", bool WithoutSuffix = false) +{ + @d.ToFullDateTime(DateNullValue) +} +@helper FriendlyDateAndTitleUser(DateTime d, User u, bool WithoutSuffix = false) +{ + @d.ToFullDateTime() +} +@helper FriendlyUser(User u, string nullValue = null, string prepend = null) +{ + if (u != null) + { + @prepend @u.Id + } + else + { + @nullValue + } +} + + @helper RadioButtonList(string id, List items, int columns = 1) { @ItemList("radio", id, items, columns) @@ -18,6 +51,19 @@ { @ItemList("checkbox", id, items, columns, alignEven, forceUniqueIds, htmlEncodeText) } +@helper CheckboxBulkSelect(string BulkSelectContainerId, string ParentJQuerySelector = null) +{Html.GetPageHelper().BundleDeferred("~/ClientScripts/Modules/Disco-jQueryExtensions"); + + @if (string.IsNullOrWhiteSpace(ParentJQuerySelector)) + { + + } + else + { + + } + +} @helper ItemList(string inputType, string id, List items, int columns = 1, bool alignEven = true, int? forceUniqueIds = null, bool htmlEncodeText = true) { int itemsPerColumn = items.Count / columns; @@ -49,35 +95,8 @@ } -@helper FriendlyDateAndUser(DateTime? d, User u, string DateNullValue = "n/a", bool WithoutSuffix = false) -{ - @FriendlyDate(d, DateNullValue, WithoutSuffix: WithoutSuffix); - @FriendlyUser(u, null, " by"); -} -@helper FriendlyDateAndUser(DateTime d, User u, bool WithoutSuffix = false) -{ - @FriendlyDate(d, WithoutSuffix: WithoutSuffix); - @FriendlyUser(u, null, " by"); -} -@helper FriendlyDateAndTitleUser(DateTime? d, User u, string DateNullValue = "n/a", bool WithoutSuffix = false) -{ - @d.FromNow(WithoutSuffix, DateNullValue) -} -@helper FriendlyDateAndTitleUser(DateTime d, User u, bool WithoutSuffix = false) -{ - @d.FromNow(WithoutSuffix) -} -@helper FriendlyUser(User u, string nullValue = null, string prepend = null) -{ - if (u != null) - { - @prepend @u.Id - } - else - { - @nullValue - } -} + + @helper Breadcrumbs(List> BreadCrumbs) { for (int index = 0; index < BreadCrumbs.Count; index++) @@ -116,17 +135,4 @@ @helper BreadcrumbsTitle(string Title) { @Title -} -@helper CheckboxBulkSelect(string BulkSelectContainerId, string ParentJQuerySelector = null) -{Html.GetPageHelper().BundleDeferred("~/ClientScripts/Modules/Disco-jQueryExtensions"); - - @if (string.IsNullOrWhiteSpace(ParentJQuerySelector)) - { - - } - else - { - - } - } \ No newline at end of file diff --git a/Disco.Web/App_Code/CommonHelpers.generated.cs b/Disco.Web/App_Code/CommonHelpers.generated.cs index 7d2f1d22..6eeaaae8 100644 --- a/Disco.Web/App_Code/CommonHelpers.generated.cs +++ b/Disco.Web/App_Code/CommonHelpers.generated.cs @@ -80,7 +80,7 @@ WriteLiteralTo(@__razor_helper_writer, ""); - - - -#line 10 "..\..\App_Code\CommonHelpers.cshtml" - -#line default -#line hidden - -}); - - } - - -public static System.Web.WebPages.HelperResult FriendlyDate(DateTime? d, string NullValue = "n/a", string ElementId = null, bool WithoutSuffix = false) -{ -return new System.Web.WebPages.HelperResult(__razor_helper_writer => { - - - -WriteLiteralTo(@__razor_helper_writer, ""); } -public static System.Web.WebPages.HelperResult RadioButtonList(string id, List items, int columns = 1) +public static System.Web.WebPages.HelperResult FriendlyDate(DateTime? d, string NullValue = "n/a", string ElementId = null, bool WithoutSuffix = false) { return new System.Web.WebPages.HelperResult(__razor_helper_writer => { +WriteLiteralTo(@__razor_helper_writer, ""); + + + +#line 14 "..\..\App_Code\CommonHelpers.cshtml" + #line default #line hidden }); -} - - -public static System.Web.WebPages.HelperResult CheckBoxList(string id, List items, int columns = 1, bool alignEven = true, int? forceUniqueIds = null, bool htmlEncodeText = true) -{ -return new System.Web.WebPages.HelperResult(__razor_helper_writer => { - - - -#line 18 "..\..\App_Code\CommonHelpers.cshtml" - - -#line default -#line hidden - - -#line 19 "..\..\App_Code\CommonHelpers.cshtml" -WriteTo(@__razor_helper_writer, ItemList("checkbox", id, items, columns, alignEven, forceUniqueIds, htmlEncodeText)); - -#line default -#line hidden - - -#line 19 "..\..\App_Code\CommonHelpers.cshtml" - - -#line default -#line hidden - -}); - -} - - -public static System.Web.WebPages.HelperResult ItemList(string inputType, string id, List items, int columns = 1, bool alignEven = true, int? forceUniqueIds = null, bool htmlEncodeText = true) -{ -return new System.Web.WebPages.HelperResult(__razor_helper_writer => { - - - -#line 22 "..\..\App_Code\CommonHelpers.cshtml" - - int itemsPerColumn = items.Count / columns; - int columnWidth = (100 / columns); - var itemNextId = 0; - -#line default -#line hidden - -WriteLiteralTo(@__razor_helper_writer, " \r\n \r\n"); - - - -#line 28 "..\..\App_Code\CommonHelpers.cshtml" - for (int i = 0; i < columns; i++) - { - -#line default -#line hidden - -WriteLiteralTo(@__razor_helper_writer, " \r\n
\r\n"); - - - -#line 51 "..\..\App_Code\CommonHelpers.cshtml" - -#line default -#line hidden - -}); - -} + } public static System.Web.WebPages.HelperResult FriendlyDateAndUser(DateTime? d, User u, string DateNullValue = "n/a", bool WithoutSuffix = false) @@ -468,35 +236,35 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 53 "..\..\App_Code\CommonHelpers.cshtml" +#line 16 "..\..\App_Code\CommonHelpers.cshtml" #line default #line hidden -#line 54 "..\..\App_Code\CommonHelpers.cshtml" +#line 17 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, FriendlyDate(d, DateNullValue, WithoutSuffix: WithoutSuffix)); #line default #line hidden -#line 54 "..\..\App_Code\CommonHelpers.cshtml" +#line 17 "..\..\App_Code\CommonHelpers.cshtml" ; #line default #line hidden -#line 55 "..\..\App_Code\CommonHelpers.cshtml" +#line 18 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, FriendlyUser(u, null, " by")); #line default #line hidden -#line 55 "..\..\App_Code\CommonHelpers.cshtml" +#line 18 "..\..\App_Code\CommonHelpers.cshtml" ; #line default @@ -513,35 +281,35 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 58 "..\..\App_Code\CommonHelpers.cshtml" +#line 21 "..\..\App_Code\CommonHelpers.cshtml" #line default #line hidden -#line 59 "..\..\App_Code\CommonHelpers.cshtml" +#line 22 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, FriendlyDate(d, WithoutSuffix: WithoutSuffix)); #line default #line hidden -#line 59 "..\..\App_Code\CommonHelpers.cshtml" +#line 22 "..\..\App_Code\CommonHelpers.cshtml" ; #line default #line hidden -#line 60 "..\..\App_Code\CommonHelpers.cshtml" +#line 23 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, FriendlyUser(u, null, " by")); #line default #line hidden -#line 60 "..\..\App_Code\CommonHelpers.cshtml" +#line 23 "..\..\App_Code\CommonHelpers.cshtml" ; #line default @@ -558,7 +326,7 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 63 "..\..\App_Code\CommonHelpers.cshtml" +#line 26 "..\..\App_Code\CommonHelpers.cshtml" #line default @@ -568,7 +336,7 @@ WriteLiteralTo(@__razor_helper_writer, " \r\n"); -#line 65 "..\..\App_Code\CommonHelpers.cshtml" +#line 28 "..\..\App_Code\CommonHelpers.cshtml" #line default #line hidden @@ -624,7 +402,7 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 67 "..\..\App_Code\CommonHelpers.cshtml" +#line 30 "..\..\App_Code\CommonHelpers.cshtml" #line default @@ -634,7 +412,7 @@ WriteLiteralTo(@__razor_helper_writer, " \r\n"); -#line 69 "..\..\App_Code\CommonHelpers.cshtml" +#line 32 "..\..\App_Code\CommonHelpers.cshtml" #line default #line hidden @@ -690,7 +478,7 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 71 "..\..\App_Code\CommonHelpers.cshtml" +#line 34 "..\..\App_Code\CommonHelpers.cshtml" if (u != null) { @@ -699,7 +487,7 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { #line hidden -#line 74 "..\..\App_Code\CommonHelpers.cshtml" +#line 37 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, prepend); #line default @@ -710,7 +498,7 @@ WriteLiteralTo(@__razor_helper_writer, " "); -#line 74 "..\..\App_Code\CommonHelpers.cshtml" +#line 37 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, u.Id); #line default @@ -730,7 +518,7 @@ WriteLiteralTo(@__razor_helper_writer, "\r\n"); -#line 75 "..\..\App_Code\CommonHelpers.cshtml" +#line 38 "..\..\App_Code\CommonHelpers.cshtml" } else { @@ -742,7 +530,7 @@ WriteLiteralTo(@__razor_helper_writer, " "); -#line 78 "..\..\App_Code\CommonHelpers.cshtml" +#line 41 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, nullValue); #line default @@ -752,7 +540,7 @@ WriteLiteralTo(@__razor_helper_writer, "\r\n"); -#line 79 "..\..\App_Code\CommonHelpers.cshtml" +#line 42 "..\..\App_Code\CommonHelpers.cshtml" } #line default @@ -763,13 +551,364 @@ WriteLiteralTo(@__razor_helper_writer, "\r\n"); } +public static System.Web.WebPages.HelperResult RadioButtonList(string id, List items, int columns = 1) +{ +return new System.Web.WebPages.HelperResult(__razor_helper_writer => { + + + +#line 47 "..\..\App_Code\CommonHelpers.cshtml" + + +#line default +#line hidden + + +#line 48 "..\..\App_Code\CommonHelpers.cshtml" +WriteTo(@__razor_helper_writer, ItemList("radio", id, items, columns)); + +#line default +#line hidden + + +#line 48 "..\..\App_Code\CommonHelpers.cshtml" + + +#line default +#line hidden + +}); + +} + + +public static System.Web.WebPages.HelperResult CheckBoxList(string id, List items, int columns = 1, bool alignEven = true, int? forceUniqueIds = null, bool htmlEncodeText = true) +{ +return new System.Web.WebPages.HelperResult(__razor_helper_writer => { + + + +#line 51 "..\..\App_Code\CommonHelpers.cshtml" + + +#line default +#line hidden + + +#line 52 "..\..\App_Code\CommonHelpers.cshtml" +WriteTo(@__razor_helper_writer, ItemList("checkbox", id, items, columns, alignEven, forceUniqueIds, htmlEncodeText)); + +#line default +#line hidden + + +#line 52 "..\..\App_Code\CommonHelpers.cshtml" + + +#line default +#line hidden + +}); + +} + + +public static System.Web.WebPages.HelperResult CheckboxBulkSelect(string BulkSelectContainerId, string ParentJQuerySelector = null) +{ +return new System.Web.WebPages.HelperResult(__razor_helper_writer => { + + + +#line 55 "..\..\App_Code\CommonHelpers.cshtml" + Html.GetPageHelper().BundleDeferred("~/ClientScripts/Modules/Disco-jQueryExtensions"); + +#line default +#line hidden + +WriteLiteralTo(@__razor_helper_writer, " \r\n"); + + + +#line 66 "..\..\App_Code\CommonHelpers.cshtml" + +#line default +#line hidden + +}); + +} + + +public static System.Web.WebPages.HelperResult ItemList(string inputType, string id, List items, int columns = 1, bool alignEven = true, int? forceUniqueIds = null, bool htmlEncodeText = true) +{ +return new System.Web.WebPages.HelperResult(__razor_helper_writer => { + + + +#line 68 "..\..\App_Code\CommonHelpers.cshtml" + + int itemsPerColumn = items.Count / columns; + int columnWidth = (100 / columns); + var itemNextId = 0; + +#line default +#line hidden + +WriteLiteralTo(@__razor_helper_writer, " \r\n \r\n"); + + + +#line 74 "..\..\App_Code\CommonHelpers.cshtml" + for (int i = 0; i < columns; i++) + { + +#line default +#line hidden + +WriteLiteralTo(@__razor_helper_writer, " \r\n
\r\n"); + + + +#line 97 "..\..\App_Code\CommonHelpers.cshtml" + +#line default +#line hidden + +}); + +} + + public static System.Web.WebPages.HelperResult Breadcrumbs(List> BreadCrumbs) { return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 82 "..\..\App_Code\CommonHelpers.cshtml" +#line 101 "..\..\App_Code\CommonHelpers.cshtml" for (int index = 0; index < BreadCrumbs.Count; index++) { @@ -784,7 +923,7 @@ WriteLiteralTo(@__razor_helper_writer, " >\r\n"); -#line 89 "..\..\App_Code\CommonHelpers.cshtml" +#line 108 "..\..\App_Code\CommonHelpers.cshtml" } if (breadCrumb.Item2 == null) { @@ -793,14 +932,14 @@ WriteLiteralTo(@__razor_helper_writer, " >\r\n"); #line hidden -#line 92 "..\..\App_Code\CommonHelpers.cshtml" +#line 111 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, breadCrumb.Item1); #line default #line hidden -#line 92 "..\..\App_Code\CommonHelpers.cshtml" +#line 111 "..\..\App_Code\CommonHelpers.cshtml" } else @@ -810,14 +949,14 @@ WriteTo(@__razor_helper_writer, breadCrumb.Item1); #line hidden -#line 96 "..\..\App_Code\CommonHelpers.cshtml" +#line 115 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, Html.GetPageHelper().ActionLink(breadCrumb.Item1, breadCrumb.Item2)); #line default #line hidden -#line 96 "..\..\App_Code\CommonHelpers.cshtml" +#line 115 "..\..\App_Code\CommonHelpers.cshtml" } } @@ -836,21 +975,21 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 101 "..\..\App_Code\CommonHelpers.cshtml" +#line 120 "..\..\App_Code\CommonHelpers.cshtml" #line default #line hidden -#line 102 "..\..\App_Code\CommonHelpers.cshtml" +#line 121 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, Title); #line default #line hidden -#line 102 "..\..\App_Code\CommonHelpers.cshtml" +#line 121 "..\..\App_Code\CommonHelpers.cshtml" #line default @@ -867,7 +1006,7 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 105 "..\..\App_Code\CommonHelpers.cshtml" +#line 124 "..\..\App_Code\CommonHelpers.cshtml" for (int index = 0; index < BreadCrumbs.Count; index++) { @@ -879,14 +1018,14 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { #line hidden -#line 111 "..\..\App_Code\CommonHelpers.cshtml" +#line 130 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, new HtmlString(" > ")); #line default #line hidden -#line 111 "..\..\App_Code\CommonHelpers.cshtml" +#line 130 "..\..\App_Code\CommonHelpers.cshtml" } @@ -894,14 +1033,14 @@ WriteTo(@__razor_helper_writer, new HtmlString(" > ")); #line hidden -#line 113 "..\..\App_Code\CommonHelpers.cshtml" +#line 132 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, breadCrumb.Item1); #line default #line hidden -#line 113 "..\..\App_Code\CommonHelpers.cshtml" +#line 132 "..\..\App_Code\CommonHelpers.cshtml" } @@ -919,122 +1058,23 @@ return new System.Web.WebPages.HelperResult(__razor_helper_writer => { -#line 117 "..\..\App_Code\CommonHelpers.cshtml" +#line 136 "..\..\App_Code\CommonHelpers.cshtml" #line default #line hidden -#line 118 "..\..\App_Code\CommonHelpers.cshtml" +#line 137 "..\..\App_Code\CommonHelpers.cshtml" WriteTo(@__razor_helper_writer, Title); #line default #line hidden -#line 118 "..\..\App_Code\CommonHelpers.cshtml" +#line 137 "..\..\App_Code\CommonHelpers.cshtml" -#line default -#line hidden - -}); - -} - - -public static System.Web.WebPages.HelperResult CheckboxBulkSelect(string BulkSelectContainerId, string ParentJQuerySelector = null) -{ -return new System.Web.WebPages.HelperResult(__razor_helper_writer => { - - - -#line 121 "..\..\App_Code\CommonHelpers.cshtml" - Html.GetPageHelper().BundleDeferred("~/ClientScripts/Modules/Disco-jQueryExtensions"); - -#line default -#line hidden - -WriteLiteralTo(@__razor_helper_writer, " \r\n"); - - - -#line 132 "..\..\App_Code\CommonHelpers.cshtml" - #line default #line hidden diff --git a/Disco.Web/Areas/API/Controllers/DeviceController.cs b/Disco.Web/Areas/API/Controllers/DeviceController.cs index 5578d614..9938bff6 100644 --- a/Disco.Web/Areas/API/Controllers/DeviceController.cs +++ b/Disco.Web/Areas/API/Controllers/DeviceController.cs @@ -373,7 +373,7 @@ namespace Disco.Web.Areas.API.Controllers var result = new { Timestamp = device.LastNetworkLogonDate, - Friendly = device.LastNetworkLogonDate.FromNow("Unknown"), + UnixEpoc = device.LastNetworkLogonDate.ToUnixEpoc(), Formatted = device.LastNetworkLogonDate.ToFullDateTime("Unknown") }; diff --git a/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs b/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs index 8c7023cf..1cda01f2 100644 --- a/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs +++ b/Disco.Web/Areas/API/Controllers/DocumentTemplateController.cs @@ -279,8 +279,8 @@ namespace Disco.Web.Areas.API.Controllers var m = undetectedDirectory.GetFiles("*.pdf").Select(f => new Models.DocumentTemplate.ImporterUndetectedFilesModel() { Id = System.IO.Path.GetFileNameWithoutExtension(f.Name), - Timestamp = f.CreationTime.ToString(), - TimestampFuzzy = f.CreationTime.FromNow() + Timestamp = f.CreationTime.ToFullDateTime(), + TimestampUnixEpoc = f.CreationTime.ToUnixEpoc() }).ToArray(); return Json(m); diff --git a/Disco.Web/Areas/API/Models/Attachment/_AttachmentModel.cs b/Disco.Web/Areas/API/Models/Attachment/_AttachmentModel.cs index 0f40326e..0ae26a1d 100644 --- a/Disco.Web/Areas/API/Models/Attachment/_AttachmentModel.cs +++ b/Disco.Web/Areas/API/Models/Attachment/_AttachmentModel.cs @@ -17,28 +17,8 @@ namespace Disco.Web.Areas.API.Models.Attachment public string Comments { get; set; } public string Filename { get; set; } public string MimeType { get; set; } - public string TimestampFuzzy - { - get - { - return Timestamp.FromNow(); - } - set - { - // Ignore - } - } - public string TimestampFull - { - get - { - return Timestamp.ToFullDateTime(); - } - set - { - // Ignore - } - } + public long TimestampUnixEpoc { get { return Timestamp.ToUnixEpoc(); } } + public string TimestampFull { get { return Timestamp.ToFullDateTime(); } } public static _AttachmentModel FromAttachment(Disco.Models.Repository.UserAttachment ua) { diff --git a/Disco.Web/Areas/API/Models/DocumentTemplate/ImporterUndetectedFilesModel.cs b/Disco.Web/Areas/API/Models/DocumentTemplate/ImporterUndetectedFilesModel.cs index d814ed16..ef6c7670 100644 --- a/Disco.Web/Areas/API/Models/DocumentTemplate/ImporterUndetectedFilesModel.cs +++ b/Disco.Web/Areas/API/Models/DocumentTemplate/ImporterUndetectedFilesModel.cs @@ -9,6 +9,6 @@ namespace Disco.Web.Areas.API.Models.DocumentTemplate { public string Id { get; set; } public string Timestamp { get; set; } - public string TimestampFuzzy { get; set; } + public long TimestampUnixEpoc { get; set; } } } \ No newline at end of file diff --git a/Disco.Web/Areas/API/Models/Job/_CommentModel.cs b/Disco.Web/Areas/API/Models/Job/_CommentModel.cs index fa8c7c96..13384164 100644 --- a/Disco.Web/Areas/API/Models/Job/_CommentModel.cs +++ b/Disco.Web/Areas/API/Models/Job/_CommentModel.cs @@ -15,28 +15,8 @@ namespace Disco.Web.Areas.API.Models.Job public string Author { get; set; } public DateTime Timestamp { get; set; } public string Comments { get; set; } - public string TimestampFuzzy - { - get - { - return Timestamp.FromNow(); - } - set - { - // Ignore - } - } - public string TimestampFull - { - get - { - return Timestamp.ToFullDateTime(); - } - set - { - // Ignore - } - } + public long TimestampUnixEpoc { get { return this.Timestamp.ToUnixEpoc(); } } + public string TimestampFull { get { return Timestamp.ToFullDateTime(); } } public static _CommentModel FromJobLog(Disco.Models.Repository.JobLog jl) { diff --git a/Disco.Web/Areas/API/Models/Job/_DateChangeModel.cs b/Disco.Web/Areas/API/Models/Job/_DateChangeModel.cs index 5e77f008..b91fb7c4 100644 --- a/Disco.Web/Areas/API/Models/Job/_DateChangeModel.cs +++ b/Disco.Web/Areas/API/Models/Job/_DateChangeModel.cs @@ -13,14 +13,14 @@ namespace Disco.Web.Areas.API.Models.Job public string UserDescription { get; set; } public string DateTimeFull { get; set; } public string DateTimeFriendly { get; set; } - public string DateTimeJavascript { get; set; } - public long DateTimeSortable { get; set; } + public string DateTimeISO8601 { get; set; } + public long DateTimeUnixEpoc { get; set; } public _DateChangeModel SetDateTime(DateTime? date) { this.DateTimeFriendly = date.FromNow(null); - this.DateTimeJavascript = date.ToJavaScript(); - this.DateTimeSortable = date.ToSortable(); + this.DateTimeISO8601 = date.ToISO8601(); + this.DateTimeUnixEpoc = date.ToUnixEpoc() ?? -1; this.DateTimeFull = date.ToFullDateTime(null); return this; diff --git a/Disco.Web/ClientSource/Scripts/Core.js b/Disco.Web/ClientSource/Scripts/Core.js index 9bb4425a..eb7b1932 100644 --- a/Disco.Web/ClientSource/Scripts/Core.js +++ b/Disco.Web/ClientSource/Scripts/Core.js @@ -41888,6 +41888,150 @@ if ( $.watermark.runOnce ) { ///#source 1 1 /ClientSource/Scripts/Core/disco.moment.extensions.js moment.lang('en-au'); +///#source 1 1 /ClientSource/Scripts/Core/livestamp.js +// Livestamp.js / v1.1.2 / (c) 2012 Matt Bradley / MIT License +(function (plugin) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery', 'moment'], plugin); + } else { + // Browser globals + plugin(jQuery, moment); + } +}(function ($, moment) { + // DISCO: Update Interval = 30 seconds (not 1 second) + var updateInterval = 30e3, + paused = false, + $livestamps = $([]), + + init = function () { + livestampGlobal.resume(); + }, + + prep = function ($el, timestamp) { + var oldData = $el.data('livestampdata'); + // DISCO: Use milliseconds, not seconds + //if (typeof timestamp == 'number') + // timestamp *= 1e3; + + $el.removeAttr('data-livestamp') + .removeData('livestamp'); + + timestamp = moment(timestamp); + if (moment.isMoment(timestamp) && !isNaN(+timestamp)) { + var newData = $.extend({}, { 'original': $el.contents() }, oldData); + newData.moment = moment(timestamp); + // DISCO: Add 'WithoutSuffix' support + newData.fromNowWithoutSuffix = $el.hasClass('noMomentSuffix'); + + $el.data('livestampdata', newData).empty(); + $livestamps.push($el[0]); + } + }, + + run = function () { + if (paused) return; + livestampGlobal.update(); + setTimeout(run, updateInterval); + }, + + livestampGlobal = { + update: function () { + $('[data-livestamp]').each(function () { + var $this = $(this); + prep($this, $this.data('livestamp')); + }); + + var toRemove = []; + $livestamps.each(function () { + var $this = $(this), + data = $this.data('livestampdata'); + + if (data === undefined) + toRemove.push(this); + else if (moment.isMoment(data.moment)) { + var from = $this.html(), + to = data.moment.fromNow(data.fromNowWithoutSuffix); // DISCO: Implement 'WithoutSuffix' support + + if (from != to) { + var e = $.Event('change.livestamp'); + $this.trigger(e, [from, to]); + if (!e.isDefaultPrevented()) + $this.html(to); + } + } + }); + + $livestamps = $livestamps.not(toRemove); + delete $livestamps.prevObject + }, + + pause: function () { + paused = true; + }, + + resume: function () { + paused = false; + run(); + }, + + interval: function (interval) { + if (interval === undefined) + return updateInterval; + updateInterval = interval; + } + }, + + livestampLocal = { + add: function ($el, timestamp) { + // DISCO: Use milliseconds, not seconds + //if (typeof timestamp == 'number') + // timestamp *= 1e3; + timestamp = moment(timestamp); + + if (moment.isMoment(timestamp) && !isNaN(+timestamp)) { + $el.each(function () { + prep($(this), timestamp); + }); + livestampGlobal.update(); + } + + return $el; + }, + + destroy: function ($el) { + $livestamps = $livestamps.not($el); + $el.each(function () { + var $this = $(this), + data = $this.data('livestampdata'); + + if (data === undefined) + return $el; + + $this + .html(data.original ? data.original : '') + .removeData('livestampdata'); + }); + + return $el; + }, + + isLivestamp: function ($el) { + return $el.data('livestampdata') !== undefined; + } + }; + + $.livestamp = livestampGlobal; + $(init); + $.fn.livestamp = function (method, options) { + if (!livestampLocal[method]) { + options = method; + method = 'add'; + } + + return livestampLocal[method](this, options); + }; +})); ///#source 1 1 /ClientSource/Scripts/Core/disco.dataTables.extensions.js jQuery.fn.dataTableExt.afnSortData['text'] = function (oSettings, iColumn) { var aData = []; @@ -41899,9 +42043,15 @@ jQuery.fn.dataTableExt.afnSortData['text'] = function (oSettings, iColumn) { jQuery.fn.dataTableExt.afnSortData['disco_datetime'] = function (oSettings, iColumn) { var aData = []; $('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () { - var d = $(this).children('span.date[data-discodatetime]'); + var d = $(this).children('span.date'); if (d.length > 0) - aData.push((d.attr('data-discodatetime')) * 1); + if (d.is('[data-livestamp]')){ + aData.push((d.attr('data-livestamp')) * 1); + } else if (d.data('livestampdata') !== undefined) { + aData.push(d.data('livestampdata').moment.valueOf()); + }else{ + aData.push(-1); + } else aData.push(-1); }); diff --git a/Disco.Web/ClientSource/Scripts/Core.js.bundle b/Disco.Web/ClientSource/Scripts/Core.js.bundle index a3fc8c3f..ad663f44 100644 --- a/Disco.Web/ClientSource/Scripts/Core.js.bundle +++ b/Disco.Web/ClientSource/Scripts/Core.js.bundle @@ -11,6 +11,7 @@ /ClientSource/Scripts/Core/moment.js /ClientSource/Scripts/Core/moment.en-au.js /ClientSource/Scripts/Core/disco.moment.extensions.js + /ClientSource/Scripts/Core/livestamp.js /ClientSource/Scripts/Core/disco.dataTables.extensions.js /ClientSource/Scripts/Core/disco.uicore.js \ No newline at end of file diff --git a/Disco.Web/ClientSource/Scripts/Core.min.js b/Disco.Web/ClientSource/Scripts/Core.min.js index ea02ade2..0f1cb6e8 100644 --- a/Disco.Web/ClientSource/Scripts/Core.min.js +++ b/Disco.Web/ClientSource/Scripts/Core.min.js @@ -1,4 +1,4 @@ -window.Modernizr=function(n,t,i){function a(n){c.cssText=n}function vt(n,t){return a(y.join(n+";")+(t||""))}function h(n,t){return typeof n===t}function v(n,t){return!!~(""+n).indexOf(t)}function lt(n,t){var u,r;for(u in n)if(r=n[u],!v(r,"-")&&c[r]!==i)return t=="pfx"?r:!0;return!1}function yt(n,t,r){var f,u;for(f in n)if(u=t[n[f]],u!==i)return r===!1?n[f]:h(u,"function")?u.bind(r||t):u;return!1}function f(n,t,i){var r=n.charAt(0).toUpperCase()+n.slice(1),u=(n+" "+ot.join(r+" ")+r).split(" ");return h(t,"string")||h(t,"undefined")?lt(u,t):(u=(n+" "+st.join(r+" ")+r).split(" "),yt(u,t,i))}function pt(){u.input=function(i){for(var r=0,u=i.length;r',n,"<\/style>"].join(""),f.id=e,(h?f:o).innerHTML+=l,o.appendChild(f),h||(o.style.background="",o.style.overflow="hidden",v=s.style.overflow,s.style.overflow="hidden",s.appendChild(o)),a=i(f,n),h?f.parentNode.removeChild(f):(o.parentNode.removeChild(o),s.style.overflow=v),!!a},at=function(t){var i=n.matchMedia||n.msMatchMedia,r;return i?i(t).matches:(l("@media "+t+" { #"+e+" { position: absolute; } }",function(t){r=(n.getComputedStyle?getComputedStyle(t,null):t.currentStyle).position=="absolute"}),r)},ct=function(){function r(r,u){u=u||t.createElement(n[r]||"div");r="on"+r;var f=r in u;return f||(u.setAttribute||(u=t.createElement("div")),u.setAttribute&&u.removeAttribute&&(u.setAttribute(r,""),f=h(u[r],"function"),h(u[r],"undefined")||(u[r]=i),u.removeAttribute(r))),u=null,f}var n={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return r}(),it={}.hasOwnProperty,rt,k;rt=h(it,"undefined")||h(it.call,"undefined")?function(n,t){return t in n&&h(n.constructor.prototype[t],"undefined")}:function(n,t){return it.call(n,t)};Function.prototype.bind||(Function.prototype.bind=function(n){var t=this,i,r;if(typeof t!="function")throw new TypeError;return i=tt.call(arguments,1),r=function(){var f,e,u;return this instanceof r?(f=function(){},f.prototype=t.prototype,e=new f,u=t.apply(e,i.concat(tt.call(arguments))),Object(u)===u)?u:e:t.apply(n,i.concat(tt.call(arguments)))},r});r.flexbox=function(){return f("flexWrap")};r.flexboxlegacy=function(){return f("boxDirection")};r.canvas=function(){var n=t.createElement("canvas");return!!(n.getContext&&n.getContext("2d"))};r.canvastext=function(){return!!(u.canvas&&h(t.createElement("canvas").getContext("2d").fillText,"function"))};r.webgl=function(){return!!n.WebGLRenderingContext};r.touch=function(){var i;return"ontouchstart"in n||n.DocumentTouch&&t instanceof DocumentTouch?i=!0:l(["@media (",y.join("touch-enabled),("),e,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(n){i=n.offsetTop===9}),i};r.geolocation=function(){return"geolocation"in navigator};r.postmessage=function(){return!!n.postMessage};r.websqldatabase=function(){return!!n.openDatabase};r.indexedDB=function(){return!!f("indexedDB",n)};r.hashchange=function(){return ct("hashchange",n)&&(t.documentMode===i||t.documentMode>7)};r.history=function(){return!!(n.history&&history.pushState)};r.draganddrop=function(){var n=t.createElement("div");return"draggable"in n||"ondragstart"in n&&"ondrop"in n};r.websockets=function(){return"WebSocket"in n||"MozWebSocket"in n};r.rgba=function(){return a("background-color:rgba(150,255,150,.5)"),v(c.backgroundColor,"rgba")};r.hsla=function(){return a("background-color:hsla(120,40%,100%,.5)"),v(c.backgroundColor,"rgba")||v(c.backgroundColor,"hsla")};r.multiplebgs=function(){return a("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(c.background)};r.backgroundsize=function(){return f("backgroundSize")};r.borderimage=function(){return f("borderImage")};r.borderradius=function(){return f("borderRadius")};r.boxshadow=function(){return f("boxShadow")};r.textshadow=function(){return t.createElement("div").style.textShadow===""};r.opacity=function(){return vt("opacity:.55"),/^0.55$/.test(c.opacity)};r.cssanimations=function(){return f("animationName")};r.csscolumns=function(){return f("columnCount")};r.cssgradients=function(){var n="background-image:";return a((n+"-webkit- ".split(" ").join("gradient(linear,left top,right bottom,from(#9f9),to(white));"+n)+y.join("linear-gradient(left top,#9f9, white);"+n)).slice(0,-n.length)),v(c.backgroundImage,"gradient")};r.cssreflections=function(){return f("boxReflect")};r.csstransforms=function(){return!!f("transform")};r.csstransforms3d=function(){var n=!!f("perspective");return n&&"webkitPerspective"in s.style&&l("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t){n=t.offsetLeft===9&&t.offsetHeight===3}),n};r.csstransitions=function(){return f("transition")};r.fontface=function(){var n;return l('@font-face {font-family:"font";src:url("https://")}',function(i,r){var f=t.getElementById("smodernizr"),u=f.sheet||f.styleSheet,e=u?u.cssRules&&u.cssRules[0]?u.cssRules[0].cssText:u.cssText||"":"";n=/src/i.test(e)&&e.indexOf(r.split(" ")[0])===0}),n};r.generatedcontent=function(){var n;return l(["#",e,"{font:0/0 a}#",e,':after{content:"',g,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){n=t.offsetHeight>=3}),n};r.video=function(){var i=t.createElement("video"),n=!1;try{(n=!!i.canPlayType)&&(n=new Boolean(n),n.ogg=i.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=i.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=i.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(r){}return n};r.audio=function(){var i=t.createElement("audio"),n=!1;try{(n=!!i.canPlayType)&&(n=new Boolean(n),n.ogg=i.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=i.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=i.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(i.canPlayType("audio/x-m4a;")||i.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(r){}return n};r.localstorage=function(){try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(n){return!1}};r.sessionstorage=function(){try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(n){return!1}};r.webworkers=function(){return!!n.Worker};r.applicationcache=function(){return!!n.applicationCache};r.svg=function(){return!!t.createElementNS&&!!t.createElementNS(p.svg,"svg").createSVGRect};r.inlinesvg=function(){var n=t.createElement("div");return n.innerHTML="",(n.firstChild&&n.firstChild.namespaceURI)==p.svg};r.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(ft.call(t.createElementNS(p.svg,"animate")))};r.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(ft.call(t.createElementNS(p.svg,"clipPath")))};for(k in r)rt(r,k)&&(b=k.toLowerCase(),u[b]=r[k](),nt.push((u[b]?"":"no-")+b));return u.input||pt(),u.addTest=function(n,t){if(typeof n=="object")for(var r in n)rt(n,r)&&u.addTest(r,n[r]);else{if(n=n.toLowerCase(),u[n]!==i)return u;t=typeof t=="function"?t():t;typeof d!="undefined"&&d&&(s.className+=" "+(t?"":"no-")+n);u[n]=t}return u},a(""),ut=o=null,function(n,t){function p(n,t){var i=n.createElement("p"),r=n.getElementsByTagName("head")[0]||n.documentElement;return i.innerHTML="x