diff --git a/Core/Entities/LeafInput.cs b/Core/Entities/LeafInput.cs index 36dfb26..e3cb2a6 100644 --- a/Core/Entities/LeafInput.cs +++ b/Core/Entities/LeafInput.cs @@ -21,6 +21,15 @@ namespace LeafWeb.Core.Entities public LeafInputStatusType CurrentStatus { get; set; } public virtual ICollection StatusHistory { get; set; } + public bool IsInProgress => CurrentStatus == LeafInputStatusType.Starting + || CurrentStatus == LeafInputStatusType.Running + || CurrentStatus == LeafInputStatusType.Finishing; + + public bool IsComplete => CurrentStatus == LeafInputStatusType.Complete; + public bool IsDeletable => !IsInProgress; + public bool IsPending => CurrentStatus == LeafInputStatusType.Pending; + public bool IsRunning => CurrentStatus == LeafInputStatusType.Running; + [Required(ErrorMessage = "Name required")] public string Name { get; set; } diff --git a/WebCms/App_Data/Models/all.dll.path b/WebCms/App_Data/Models/all.dll.path index 31d7a0b..d9194b5 100644 --- a/WebCms/App_Data/Models/all.dll.path +++ b/WebCms/App_Data/Models/all.dll.path @@ -1 +1 @@ -C:\Users\poprhythm\AppData\Local\Temp\Temporary ASP.NET Files\vs\f80e29bb\faae20bf\App_Web_all.generated.cs.8f9494c4.vnu9hbgh.dll \ No newline at end of file +C:\Users\poprhythm\AppData\Local\Temp\Temporary ASP.NET Files\vs\f80e29bb\faae20bf\App_Web_all.generated.cs.8f9494c4.xctgaqtc.dll \ No newline at end of file diff --git a/WebCms/Content/style.css b/WebCms/Content/style.css index 780a0df..7bcbe8a 100644 --- a/WebCms/Content/style.css +++ b/WebCms/Content/style.css @@ -39,7 +39,7 @@ a.banner-link:hover { .headline-icon { /* http://glyphicons.bootstrapcheatsheets.com/ */ } .headline-icon h1:after { - color: #c4e29d; + color: rgba(172, 214, 118, 0.8); font-family: "Glyphicons Halflings"; font-size: .8em; padding-left: 10px; } @@ -61,6 +61,11 @@ a.banner-link:hover { font-size: .8em; padding-left: 5px; } +.status.status-pending { + color: #f0ad4e; } + .status.status-pending:after { + content: "\e023"; } + .status.status-complete { color: #337ab7; } .status.status-complete:after { @@ -71,15 +76,12 @@ a.banner-link:hover { .status.status-exception:after { content: "\e101"; } -.status.status-running, .status.status-pending, .status.status-starting, .status.status-finishing { +.status.status-running, .status.status-starting, .status.status-finishing { color: #3c763d; } .status.status-running:after { content: "\e089"; } -.status.status-pending:after { - content: "\e023"; } - .status.status-starting:after { content: "\e026"; } diff --git a/WebCms/Content/style.min.css b/WebCms/Content/style.min.css index 98192c6..e661934 100644 --- a/WebCms/Content/style.min.css +++ b/WebCms/Content/style.min.css @@ -1 +1 @@ -h1{padding:24px 0 12px 0;}p{padding:12px 0;}footer{margin-top:24px !important;}.row-no-padding [class*="col-"]{padding-left:0 !important;padding-right:0 !important;}.home .dark .row:first-child .column:first-child h1{padding-top:0;}.home .blogarchive{padding-top:20px;}.banner-link{white-space:normal;padding:20px;background:#000;background:rgba(0,0,0,.5);-moz-border-radius:10px;border-radius:10px;}.banner-link .glyphicon{color:#8cc641;}a.banner-link:hover{text-decoration:none;background:rgba(0,0,0,.6);}a.banner-link:hover .glyphicon{color:#a8ed4e;}.headline-icon h1:after{color:#c4e29d;font-family:"Glyphicons Halflings";font-size:.8em;padding-left:10px;}.headline-icon.headline-icon-file h1:after{content:"";}.headline-icon.headline-icon-leaf h1:after{content:"";}.headline-icon.headline-icon-question h1:after{content:"";}.headline-icon.headline-icon-stats h1:after{content:"";}.headline-icon.headline-icon-user h1:after{content:"";}.headline-icon.headline-icon-list h1:after{content:"";}.status:after{font-family:"Glyphicons Halflings";font-size:.8em;padding-left:5px;}.status.status-complete{color:#337ab7;}.status.status-complete:after{content:"";}.status.status-exception{color:#a94442;}.status.status-exception:after{content:"";}.status.status-running,.status.status-pending,.status.status-starting,.status.status-finishing{color:#3c763d;}.status.status-running:after{content:"";}.status.status-pending:after{content:"";}.status.status-starting:after{content:"";}.status.status-finishing:after{content:"";}#chart{padding-top:20px;}.btn-file{position:relative;overflow:hidden;}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;outline:none;background:#fff;cursor:inherit;display:block;}form .validation-summary-errors ul{list-style-type:none;}.autocomplete-suggestions{border:1px solid #999;background:#fff;overflow:auto;}.autocomplete-suggestion{padding:2px 5px;white-space:nowrap;overflow:hidden;}.autocomplete-selected{background:#f0f0f0;}.autocomplete-suggestions strong{font-weight:normal;color:#39f;}.autocomplete-group{padding:2px 5px;}.autocomplete-group strong{display:block;border-bottom:1px solid #000;}.toggle{width:15px;} \ No newline at end of file +h1{padding:24px 0 12px 0;}p{padding:12px 0;}footer{margin-top:24px !important;}.row-no-padding [class*="col-"]{padding-left:0 !important;padding-right:0 !important;}.home .dark .row:first-child .column:first-child h1{padding-top:0;}.home .blogarchive{padding-top:20px;}.banner-link{white-space:normal;padding:20px;background:#000;background:rgba(0,0,0,.5);-moz-border-radius:10px;border-radius:10px;}.banner-link .glyphicon{color:#8cc641;}a.banner-link:hover{text-decoration:none;background:rgba(0,0,0,.6);}a.banner-link:hover .glyphicon{color:#a8ed4e;}.headline-icon h1:after{color:rgba(172,214,118,.8);font-family:"Glyphicons Halflings";font-size:.8em;padding-left:10px;}.headline-icon.headline-icon-file h1:after{content:"";}.headline-icon.headline-icon-leaf h1:after{content:"";}.headline-icon.headline-icon-question h1:after{content:"";}.headline-icon.headline-icon-stats h1:after{content:"";}.headline-icon.headline-icon-user h1:after{content:"";}.headline-icon.headline-icon-list h1:after{content:"";}.status:after{font-family:"Glyphicons Halflings";font-size:.8em;padding-left:5px;}.status.status-pending{color:#f0ad4e;}.status.status-pending:after{content:"";}.status.status-complete{color:#337ab7;}.status.status-complete:after{content:"";}.status.status-exception{color:#a94442;}.status.status-exception:after{content:"";}.status.status-running,.status.status-starting,.status.status-finishing{color:#3c763d;}.status.status-running:after{content:"";}.status.status-starting:after{content:"";}.status.status-finishing:after{content:"";}#chart{padding-top:20px;}.btn-file{position:relative;overflow:hidden;}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;outline:none;background:#fff;cursor:inherit;display:block;}form .validation-summary-errors ul{list-style-type:none;}.autocomplete-suggestions{border:1px solid #999;background:#fff;overflow:auto;}.autocomplete-suggestion{padding:2px 5px;white-space:nowrap;overflow:hidden;}.autocomplete-selected{background:#f0f0f0;}.autocomplete-suggestions strong{font-weight:normal;color:#39f;}.autocomplete-group{padding:2px 5px;}.autocomplete-group strong{display:block;border-bottom:1px solid #000;}.toggle{width:15px;} \ No newline at end of file diff --git a/WebCms/Content/style.scss b/WebCms/Content/style.scss index a57d106..4066304 100644 --- a/WebCms/Content/style.scss +++ b/WebCms/Content/style.scss @@ -59,7 +59,7 @@ a.banner-link:hover { .headline-icon { h1:after { - color: #c4e29d; + color: rgba(172, 214, 118, 0.8); font-family: "Glyphicons Halflings"; font-size: .8em; padding-left: 10px; @@ -95,7 +95,13 @@ a.banner-link:hover { font-size: .8em; padding-left: 5px; } - + + &.status-pending { + color: #f0ad4e; + &:after { + content:"\e023"; + } + } &.status-complete { color: #337ab7; &:after { @@ -109,15 +115,12 @@ a.banner-link:hover { } } - &.status-running,&.status-pending,&.status-starting,&.status-finishing { + &.status-running,&.status-starting,&.status-finishing { color: #3c763d; } &.status-running:after { content:"\e089"; } - &.status-pending:after { - content:"\e023"; - } &.status-starting:after { content:"\e026"; } diff --git a/WebCms/Controllers/EnforceTrueAttribute.cs b/WebCms/Controllers/EnforceTrueAttribute.cs new file mode 100644 index 0000000..3a03418 --- /dev/null +++ b/WebCms/Controllers/EnforceTrueAttribute.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Web.Mvc; + +namespace LeafWeb.WebCms.Controllers +{ + // http://stackoverflow.com/a/9036075/99492 + public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable + { + public override bool IsValid(object value) + { + if (value == null) return false; + if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties."); + return (bool)value; + } + + public override string FormatErrorMessage(string name) + { + return "The " + name + " field must be checked in order to continue."; + } + + public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) + { + yield return new ModelClientValidationRule + { + ErrorMessage = + string.IsNullOrEmpty(ErrorMessage) + ? FormatErrorMessage(metadata.DisplayName) + : ErrorMessage, + ValidationType = "enforcetrue" + }; + } + } +} \ No newline at end of file diff --git a/WebCms/Controllers/QueueController.cs b/WebCms/Controllers/QueueController.cs index e03fd78..63e83a7 100644 --- a/WebCms/Controllers/QueueController.cs +++ b/WebCms/Controllers/QueueController.cs @@ -1,8 +1,10 @@ using System.Linq; using System.Web.Mvc; +using Hangfire; using LeafWeb.Core.Entities; using LeafWeb.Core.Utility; using LeafWeb.WebCms.Models; +using LeafWeb.WebCms.Services; namespace LeafWeb.WebCms.Controllers { @@ -73,23 +75,45 @@ namespace LeafWeb.WebCms.Controllers return new FileContentResult(zip, "application/zip") { FileDownloadName = filename }; } + [ActionLog] public ActionResult Delete(int id) { var leafInput = DataService.GetLeafInput(id); - var viewModel = new LeafInputCreate(); - return View(viewModel); - } - [HttpPost, ActionName("Delete")] - [ActionLog] - public ActionResult DeleteConfirmed(int id) - { - // TODO: don't allow currently running LeafInput to be deleted - var leafInput = DataService.GetLeafInput(id); + // don't allow currently running LeafInput to be deleted + if (leafInput.IsRunning) + { + SetStatusMessage($"LeafInput '{leafInput.Identifier}' is currently running!", StatusType.Error); + return View(Request.UrlReferrer.ToString()); + } + DataService.DeleteLeafInput(leafInput); SetStatusMessage($"LeafInput '{leafInput.Identifier}' deleted"); return RedirectToAction("Index"); } + + [ActionLog] + public ActionResult SendUserDownloadLink(int id) + { + var leafInput = DataService.GetLeafInput(id); + if (!leafInput.IsComplete) + { + SetStatusMessage($"LeafInput '{leafInput.Identifier}' is not complete!", StatusType.Error); + } + else + { + var leafInputId = leafInput.Id; + BackgroundJob.Enqueue(e => e.SendLeafWebComplete(leafInputId)); + SetStatusMessage($"LeafInput '{leafInput.Identifier}' download link sent", StatusType.Success); + } + return View(Request.UrlReferrer.ToString()); + } + + [ActionLog] + public ActionResult SendUserChartLink(int id) + { + throw new System.NotImplementedException(); + } } } \ No newline at end of file diff --git a/WebCms/Models/LeafInputCreate.cs b/WebCms/Models/LeafInputCreate.cs index 825ed99..6557776 100644 --- a/WebCms/Models/LeafInputCreate.cs +++ b/WebCms/Models/LeafInputCreate.cs @@ -2,6 +2,7 @@ using AutoMapper; using LeafWeb.Core.DAL; using LeafWeb.Core.Entities; +using LeafWeb.WebCms.Controllers; namespace LeafWeb.WebCms.Models { @@ -20,7 +21,7 @@ namespace LeafWeb.WebCms.Models [Display(Name = "Confirm email address")] [Required(ErrorMessage = "Enter email exactly as above")] - [Compare("Email")] + [System.ComponentModel.DataAnnotations.Compare("Email")] public string EmailConfirm { get; set; } [Display(Name = "A unique identifier for this data")] @@ -35,6 +36,10 @@ namespace LeafWeb.WebCms.Models [Required(ErrorMessage = "A Photosynthetic pathway must be chosen")] public SelectListViewModel PhotosynthesisType { get; set; } + [UIHint("TermsOfService")] + [EnforceTrue(ErrorMessage = "Terms of Service must be accepted to continue")] + public bool? TermsOfService { get; set; } + static LeafInputCreate() { Mapper.CreateMap() diff --git a/WebCms/Models/LeafInputDetails.cs b/WebCms/Models/LeafInputDetails.cs index 20ecc2b..5ac1510 100644 --- a/WebCms/Models/LeafInputDetails.cs +++ b/WebCms/Models/LeafInputDetails.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Web.Mvc; using AutoMapper; using LeafWeb.Core.Entities; using LeafWeb.Core.Utility; @@ -9,6 +11,9 @@ namespace LeafWeb.WebCms.Models { public class LeafInputDetails { + [HiddenInput(DisplayValue = false)] + public int LeafInputId { get; set; } + [Display(Name = "Name")] [Required(ErrorMessage = "Name required")] [RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Please provide full name")] @@ -48,6 +53,18 @@ namespace LeafWeb.WebCms.Models [UIHint("LeafInputStatusViewModels")] public List StatusHistory { get; set; } + [HiddenInput(DisplayValue = false)] + public bool HasLeafChart { get; set; } + + [HiddenInput(DisplayValue = false)] + public bool IsRunning { get; set; } + + [HiddenInput(DisplayValue = false)] + public bool IsComplete { get; set; } + + [HiddenInput(DisplayValue = false)] + public bool IsDeletable { get; set; } + static LeafInputDetails() { Mapper.CreateMap().ConvertUsing(file => file?.Contents.GetString()); @@ -55,7 +72,9 @@ namespace LeafWeb.WebCms.Models Mapper.CreateMap().ConvertUsing(st => st.ToString()); Mapper.CreateMap().ConvertUsing(st => new LeafInputStatus()); Mapper.CreateMap(); - Mapper.CreateMap(); + Mapper.CreateMap() + .ForMember(dest => dest.LeafInputId, opt => opt.MapFrom(src => src.Id)) + .ForMember(dest => dest.HasLeafChart, opt => opt.ResolveUsing(src => src.OutputFiles.Any(o => o.IsLeafChartFile))); } public LeafInputDetails(LeafInput leafInput) diff --git a/WebCms/Models/ResultStatusViewModel.cs b/WebCms/Models/ResultStatusViewModel.cs index d44851e..9ce91cb 100644 --- a/WebCms/Models/ResultStatusViewModel.cs +++ b/WebCms/Models/ResultStatusViewModel.cs @@ -12,7 +12,12 @@ namespace LeafWeb.WebCms.Models public string LeafInputSiteId { get; set; } public string LeafInputPhotosynthesisType { get; set; } public bool HasLeafChart { get; set; } + public bool IsRunning { get; set; } + public bool IsComplete { get; set; } + public bool IsDeletable { get; set; } + public bool IsPending { get; set; } public string CurrentStatus { get; set; } + //public string[] ErrorMessages { get; set; } //public string[] LeafOutputFilenames { get; set; } //public bool HasLeafChartOutputFile { get; set; } diff --git a/WebCms/Services/EmailNotificationService.cs b/WebCms/Services/EmailNotificationService.cs index 0b58675..b5b02e3 100644 --- a/WebCms/Services/EmailNotificationService.cs +++ b/WebCms/Services/EmailNotificationService.cs @@ -17,7 +17,7 @@ namespace LeafWeb.WebCms.Services private readonly string _emailFromAddress; - private const string EmailSuccessSubject = "LeafWeb Results"; + private const string EmailSuccessSubject = "LeafWeb results"; private const string EmailErrorSubject = "LeafWeb processing error"; private const string EmailSystemErrorSubject = "LeafWeb system error"; @@ -58,6 +58,11 @@ namespace LeafWeb.WebCms.Services public void SendLeafWebComplete(int leafInputId) { var leafInput = _dataService.GetLeafInput(leafInputId); + if (leafInput.CurrentStatus != LeafInputStatusType.Complete) + { + Logger.Error($"Attempting to SendLeafWebComplete when status is not complete for leafInput: {leafInput}, current status: {leafInput.CurrentStatus}"); + throw new ArgumentException($"Attempting to SendLeafWebComplete when status is not complete for leafInput: {leafInput}, current status: {leafInput.CurrentStatus}"); + } var outputErrorMessage = leafInput.OutputErrorMessage; if (outputErrorMessage != null) diff --git a/WebCms/Services/PiscalQueue/PiscalQueueManager.cs b/WebCms/Services/PiscalQueue/PiscalQueueManager.cs index 581cae4..ea1a131 100644 --- a/WebCms/Services/PiscalQueue/PiscalQueueManager.cs +++ b/WebCms/Services/PiscalQueue/PiscalQueueManager.cs @@ -83,15 +83,15 @@ namespace LeafWeb.WebCms.Services.PiscalQueue Logger.InfoFormat("LeafInput: {0}, Starting", pendingInputId); try { - DataService.SetLeafInputStatus(pendingInput, LeafInputStatusType.Starting, - details: $"File count: {pendingInput.InputFiles.Count}"); + DataService.SetLeafInputStatus(pendingInput, LeafInputStatusType.Starting, "Copying input to Piscal", + $"File count: {pendingInput.InputFiles.Count}"); BackgroundJobEnqueueRetry(c => c.DoWork(pendingInputId)); } catch (Exception ex) { var errorMessage = FormatException(ex); Logger.Error(errorMessage); - DataService.SetLeafInputStatus(pendingInput, LeafInputStatusType.Exception, ex.Message, errorMessage); + DataService.SetLeafInputStatus(pendingInput, LeafInputStatusType.Exception, "Exception while StartPending", errorMessage); } } @@ -108,8 +108,9 @@ namespace LeafWeb.WebCms.Services.PiscalQueue { case PiscalStatus.NotStarted: // if it's not started - this is unusual state - PiscalWarningHandler($"LeafInput: {leafInput.Id}, Piscal reporting Not Started, setting to pending to retry", leafInput); - DataService.SetLeafInputStatus(leafInput, LeafInputStatusType.Pending); + var pendingToRetry = "Piscal reporting Not Started, setting to Pending to retry"; + PiscalWarningHandler($"LeafInput: {leafInput.Id}, {pendingToRetry}", leafInput); + DataService.SetLeafInputStatus(leafInput, LeafInputStatusType.Pending, details: pendingToRetry); break; case PiscalStatus.Running: @@ -118,7 +119,7 @@ namespace LeafWeb.WebCms.Services.PiscalQueue break; case PiscalStatus.Complete: - DataService.SetLeafInputStatus(leafInput, LeafInputStatusType.Finishing); + DataService.SetLeafInputStatus(leafInput, LeafInputStatusType.Finishing, "Copying output from Piscal"); BackgroundJobEnqueueRetry(s => s.DoWork(leafInputId)); break; diff --git a/WebCms/Services/PiscalQueue/StartPending.cs b/WebCms/Services/PiscalQueue/StartPending.cs index df2f2ee..37ca0df 100644 --- a/WebCms/Services/PiscalQueue/StartPending.cs +++ b/WebCms/Services/PiscalQueue/StartPending.cs @@ -10,7 +10,7 @@ namespace LeafWeb.WebCms.Services.PiscalQueue PiscalService.Run(leafInput); - DataService.SetLeafInputStatus(leafInput, LeafInputStatusType.Running, details: $"ServiceInfo: {PiscalService.ServiceDescription}"); + DataService.SetLeafInputStatus(leafInput, LeafInputStatusType.Running, "Starting Piscal", $"{PiscalService.ServiceDescription}"); } } } \ No newline at end of file diff --git a/WebCms/Views/LeafInput/Create.cshtml b/WebCms/Views/LeafInput/Create.cshtml index 158d1e8..6058fee 100644 --- a/WebCms/Views/LeafInput/Create.cshtml +++ b/WebCms/Views/LeafInput/Create.cshtml @@ -61,7 +61,7 @@ @Html.EditorFor(m => m.Name) @Html.EditorFor(m => m.Email) @Html.EditorFor(m => m.EmailConfirm) - Terms of Service + @Html.EditorFor(m => m.TermsOfService) } diff --git a/WebCms/Views/Queue/Details.cshtml b/WebCms/Views/Queue/Details.cshtml index 2b3e153..a897cee 100644 --- a/WebCms/Views/Queue/Details.cshtml +++ b/WebCms/Views/Queue/Details.cshtml @@ -1,3 +1,35 @@ @model LeafWeb.WebCms.Models.LeafInputDetails +
+ @Html.Partial("DisplayTemplates/_ChartButton", Model.LeafInputId, new ViewDataDictionary { { "Disabled", !Model.HasLeafChart } }) +
+ + + + + + @Html.DisplayForModel() diff --git a/WebCms/Views/Queue/Index.cshtml b/WebCms/Views/Queue/Index.cshtml index df480d1..91608ab 100644 --- a/WebCms/Views/Queue/Index.cshtml +++ b/WebCms/Views/Queue/Index.cshtml @@ -24,17 +24,17 @@ @@ -48,4 +48,27 @@ @helper ChartLink(dynamic item) { @Html.Partial("DisplayTemplates/_ChartLink", (int)item.LeafInputId) +} + +@helper DownloadInput(dynamic item) +{ + + Input + +} +@helper DownloadOutputToUser(dynamic item) +{ + + ToUser + +} +@helper DeleteLink(dynamic item) +{ + + Delete + +} +@helper DisableItem(bool disabled) +{ +if (disabled) {class="disabled"} } \ No newline at end of file diff --git a/WebCms/Views/Results/Index.cshtml b/WebCms/Views/Results/Index.cshtml index 33aa045..f747d12 100644 --- a/WebCms/Views/Results/Index.cshtml +++ b/WebCms/Views/Results/Index.cshtml @@ -18,8 +18,5 @@ @helper ChartLink(dynamic item) { -if (item.HasLeafChart) -{ - @Html.Partial("DisplayTemplates/_ChartButton", (int)item.LeafInputId) -} + @Html.Partial("DisplayTemplates/_ChartButton", (int)item.LeafInputId, new ViewDataDictionary { { "Disabled", !item.HasLeafChart }, {"xs", true} }) } \ No newline at end of file diff --git a/WebCms/Views/Shared/DisplayTemplates/_ChartButton.cshtml b/WebCms/Views/Shared/DisplayTemplates/_ChartButton.cshtml index caea094..57866cf 100644 --- a/WebCms/Views/Shared/DisplayTemplates/_ChartButton.cshtml +++ b/WebCms/Views/Shared/DisplayTemplates/_ChartButton.cshtml @@ -1,6 +1,13 @@ @model int - +@{ + var url = UmbracoContext.Current.UrlProvider.GetUrl(1100); + var disabled = ViewData.ContainsKey("Disabled") && (bool) ViewData["Disabled"]; + var xs = ViewData.ContainsKey("xs") && (bool) ViewData["xs"]; +} +title="No chart has been generated"}} /> Chart - - + \ No newline at end of file diff --git a/WebCms/Views/Shared/DisplayTemplates/_ChartLink.cshtml b/WebCms/Views/Shared/DisplayTemplates/_ChartLink.cshtml index df0a5dd..f51d052 100644 --- a/WebCms/Views/Shared/DisplayTemplates/_ChartLink.cshtml +++ b/WebCms/Views/Shared/DisplayTemplates/_ChartLink.cshtml @@ -1,6 +1,8 @@ @model int - +@{ + var url = UmbracoContext.Current.UrlProvider.GetUrl(1100); +} + Chart - - + \ No newline at end of file diff --git a/WebCms/Views/Shared/DisplayTemplates/_DetailsLink.cshtml b/WebCms/Views/Shared/DisplayTemplates/_DetailsLink.cshtml index c7a1017..8717e16 100644 --- a/WebCms/Views/Shared/DisplayTemplates/_DetailsLink.cshtml +++ b/WebCms/Views/Shared/DisplayTemplates/_DetailsLink.cshtml @@ -1,4 +1,7 @@ @model int - +@{ + var url = UmbracoContext.Current.UrlProvider.GetUrl(1111); +} + Details diff --git a/WebCms/Views/Shared/EditorTemplates/TermsOfService.cshtml b/WebCms/Views/Shared/EditorTemplates/TermsOfService.cshtml new file mode 100644 index 0000000..c21906d --- /dev/null +++ b/WebCms/Views/Shared/EditorTemplates/TermsOfService.cshtml @@ -0,0 +1,23 @@ +@using LeafWeb.WebCms.Utility +@model bool? + +@{ + var propertyName = ViewData.ModelMetadata.PropertyName; + var isChecked = Model.HasValue && Model.Value; +} + +
+
+ +
+ @Html.ValidationMessageFor(m => m, null, new { @class = "help-block" }) +
\ No newline at end of file diff --git a/WebCms/WebCms.csproj b/WebCms/WebCms.csproj index 04cb598..6287ef0 100644 --- a/WebCms/WebCms.csproj +++ b/WebCms/WebCms.csproj @@ -803,6 +803,8 @@ + + Web.config @@ -825,6 +827,7 @@ + diff --git a/WebCms/scripts/LeafInputCreate.js b/WebCms/scripts/LeafInputCreate.js index 681b51b..ca80deb 100644 --- a/WebCms/scripts/LeafInputCreate.js +++ b/WebCms/scripts/LeafInputCreate.js @@ -1,6 +1,12 @@ function initFileUpload(objectContext) { "use strict"; + // enforce true attribute client support + jQuery.validator.addMethod("enforcetrue", function (value, element, param) { + return element.checked; + }); + jQuery.validator.unobtrusive.adapters.addBool("enforcetrue"); + // We use the upload handler integrated into Backload: // In this example we set an objectContect (id) in the url query (or as form parameter). // You can use a user id as objectContext give users only access to their own uploads. diff --git a/WebCms/scripts/site.js b/WebCms/scripts/site.js index 3f5dbfa..001414d 100644 --- a/WebCms/scripts/site.js +++ b/WebCms/scripts/site.js @@ -1,5 +1,10 @@ (function($) { + // disable anchors in menu links which are disabled + $("li.disabled a").click(function () { + return false; + }); + // Making elements equal height var equalheight = function(container){