From a29de1ecb8a8536e950376ebd2d71a37185d63f3 Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Thu, 8 Dec 2016 12:15:47 -0500 Subject: [PATCH] Charts, login, manage queue, styling --- WebCms/App_Data/Models/all.generated.cs | 22 +- WebCms/App_Data/Models/models.generated.cs | 24 +- WebCms/App_Data/Models/models.hash | 2 +- WebCms/Content/style.css | 93 +++++++- WebCms/Controllers/ChartController.cs | 211 ++++++++++++++++++ WebCms/Controllers/FluxnetSiteController.cs | 2 +- WebCms/Controllers/QueueController.cs | 95 ++++++++ WebCms/Models/ChartViewModel.cs | 18 ++ WebCms/Views/BlogOverview.cshtml | 32 +-- WebCms/Views/Chart/DataError.cshtml | 4 + WebCms/Views/Chart/Index.cshtml | 20 ++ WebCms/Views/Home.cshtml | 26 --- WebCms/Views/LeafInput/Create.cshtml | 2 +- WebCms/Views/MacroPartials/BannerLink.cshtml | 11 + .../Views/MacroPartials/BlogHighlights.cshtml | 28 +++ WebCms/Views/MacroPartials/Chart.cshtml | 5 + .../MacroPartials/Membership/Login.cshtml | 41 ++++ WebCms/Views/MacroPartials/Queue.cshtml | 5 + WebCms/Views/Master.cshtml | 20 +- WebCms/Views/Partials/BottomNavigation.cshtml | 31 ++- WebCms/Views/Partials/LoginStatus.cshtml | 35 +++ WebCms/Views/Partials/MainNavigation.cshtml | 24 +- WebCms/Views/Queue/Details.cshtml | 3 + WebCms/Views/Queue/DownloadNotFound.cshtml | 10 + WebCms/Views/Queue/Index.cshtml | 49 ++++ WebCms/Views/Results/Index.cshtml | 20 +- WebCms/Views/Shared/_StatusMessage.cshtml | 2 +- WebCms/Views/TextPage.cshtml | 6 +- WebCms/WebCms.csproj | 15 ++ WebCms/scripts/Chart.js | 42 ++++ 30 files changed, 808 insertions(+), 90 deletions(-) create mode 100644 WebCms/Controllers/ChartController.cs create mode 100644 WebCms/Controllers/QueueController.cs create mode 100644 WebCms/Models/ChartViewModel.cs create mode 100644 WebCms/Views/Chart/DataError.cshtml create mode 100644 WebCms/Views/Chart/Index.cshtml create mode 100644 WebCms/Views/MacroPartials/BannerLink.cshtml create mode 100644 WebCms/Views/MacroPartials/BlogHighlights.cshtml create mode 100644 WebCms/Views/MacroPartials/Chart.cshtml create mode 100644 WebCms/Views/MacroPartials/Membership/Login.cshtml create mode 100644 WebCms/Views/MacroPartials/Queue.cshtml create mode 100644 WebCms/Views/Partials/LoginStatus.cshtml create mode 100644 WebCms/Views/Queue/Details.cshtml create mode 100644 WebCms/Views/Queue/DownloadNotFound.cshtml create mode 100644 WebCms/Views/Queue/Index.cshtml create mode 100644 WebCms/scripts/Chart.js diff --git a/WebCms/App_Data/Models/all.generated.cs b/WebCms/App_Data/Models/all.generated.cs index 06f8875..1fbc5ae 100644 --- a/WebCms/App_Data/Models/all.generated.cs +++ b/WebCms/App_Data/Models/all.generated.cs @@ -8,7 +8,7 @@ using Umbraco.Web; using Umbraco.ModelsBuilder; using Umbraco.ModelsBuilder.Umbraco; [assembly: PureLiveAssembly] -[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "9bd3b2ce6fad5710")] +[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "72e45477d4ceda7e")] [assembly:System.Reflection.AssemblyVersion("0.0.0.1")] @@ -216,7 +216,7 @@ namespace Umbraco.Web.PublishedContentModels } /// - /// Hide in bottom navigation? + /// Hide in navigation? /// [ImplementPropertyType("umbracoNaviHide")] public bool UmbracoNaviHide @@ -250,6 +250,15 @@ namespace Umbraco.Web.PublishedContentModels return PublishedContentModelUtility.GetModelPropertyType(GetModelContentType(), selector); } + /// + /// Chart: loads scripts for charting + /// + [ImplementPropertyType("chart")] + public bool Chart + { + get { return this.GetPropertyValue("chart"); } + } + /// /// Content /// @@ -267,6 +276,15 @@ namespace Umbraco.Web.PublishedContentModels { get { return this.GetPropertyValue("leafInputBackload"); } } + + /// + /// Hide in Navigation? + /// + [ImplementPropertyType("umbracoNaviHide")] + public bool UmbracoNaviHide + { + get { return this.GetPropertyValue("umbracoNaviHide"); } + } } /// Folder diff --git a/WebCms/App_Data/Models/models.generated.cs b/WebCms/App_Data/Models/models.generated.cs index 83168cc..214179f 100644 --- a/WebCms/App_Data/Models/models.generated.cs +++ b/WebCms/App_Data/Models/models.generated.cs @@ -19,8 +19,8 @@ using Umbraco.ModelsBuilder; using Umbraco.ModelsBuilder.Umbraco; [assembly: PureLiveAssembly] -[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "9bd3b2ce6fad5710")] -[assembly:System.Reflection.AssemblyVersion("0.0.0.1")] +[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "72e45477d4ceda7e")] +[assembly:System.Reflection.AssemblyVersion("0.0.0.2")] namespace Umbraco.Web.PublishedContentModels { @@ -200,7 +200,7 @@ namespace Umbraco.Web.PublishedContentModels } /// - /// Hide in bottom navigation? + /// Hide in navigation? /// [ImplementPropertyType("umbracoNaviHide")] public bool UmbracoNaviHide @@ -234,6 +234,15 @@ namespace Umbraco.Web.PublishedContentModels return PublishedContentModelUtility.GetModelPropertyType(GetModelContentType(), selector); } + /// + /// Chart: loads scripts for charting + /// + [ImplementPropertyType("chart")] + public bool Chart + { + get { return this.GetPropertyValue("chart"); } + } + /// /// Content /// @@ -251,6 +260,15 @@ namespace Umbraco.Web.PublishedContentModels { get { return this.GetPropertyValue("leafInputBackload"); } } + + /// + /// Hide in Navigation? + /// + [ImplementPropertyType("umbracoNaviHide")] + public bool UmbracoNaviHide + { + get { return this.GetPropertyValue("umbracoNaviHide"); } + } } /// Folder diff --git a/WebCms/App_Data/Models/models.hash b/WebCms/App_Data/Models/models.hash index bc0e112..971001e 100644 --- a/WebCms/App_Data/Models/models.hash +++ b/WebCms/App_Data/Models/models.hash @@ -1 +1 @@ -9bd3b2ce6fad5710 \ No newline at end of file +72e45477d4ceda7e \ No newline at end of file diff --git a/WebCms/Content/style.css b/WebCms/Content/style.css index 75957b6..7ecd051 100644 --- a/WebCms/Content/style.css +++ b/WebCms/Content/style.css @@ -2,25 +2,110 @@ /* EDITOR PROPERTIES - PLEASE DON'T DELETE THIS LINE TO AVOID DUPLICATE PROPERTIES */ h1 { - padding: 24px 0 0 0; + padding: 24px 0 12px 0; } p { padding: 12px 0; } -.home .row:first-child .column:first-child h1 { +.home .dark .row:first-child .column:first-child h1 { padding-top: 0px; } -.home .row:first-child .column div { - padding: 10px; +.home .blogarchive { + padding-top: 20px; +} + +.banner-link { + white-space: normal; + padding: 20px; background: #000000; background: rgba(0, 0, 0, .5); -moz-border-radius: 10px; border-radius: 10px; /* standards-compliant: (IE) */ } +.banner-link .glyphicon { + color: #8cc641; +} + +a.banner-link:hover { + text-decoration: none; + background: rgba(0, 0, 0, 0.6); +} +a.banner-link:hover .glyphicon { + color: #a8ed4e; +} + +.headline-icon h1:after { + color: #8cc641; + font-family: "Glyphicons Halflings"; + font-size: .8em; + padding-left: 10px; +} + +/* http://glyphicons.bootstrapcheatsheets.com/ */ +.headline-icon.headline-icon-none h1:after { +} +.headline-icon.headline-icon-file h1:after { + content:"\e022"; +} +.headline-icon.headline-icon-leaf h1:after { + content:"\e103"; +} +.headline-icon.headline-icon-question h1:after { + content:"\e085"; +} +.headline-icon.headline-icon-stats h1:after { + content:"\e185"; +} +.headline-icon.headline-icon-user h1:after { + content:"\e008"; +} +.headline-icon.headline-icon-list h1:after { + content:"\e012"; +} + +.status:after { + font-family: "Glyphicons Halflings"; + font-size: .8em; + padding-left: 5px; +} + +.status.status-complete { + color: #337ab7; +} +.status.status-complete:after { + content:"\e084"; +} + +.status.status-running,.status.status-pending,.status.status-starting,.status.status-finishing { + color: #3c763d; +} +.status.status-running:after { + content:"\e089"; +} +.status.status-starting:after { + content:"\e026"; +} +.status.status-pending:after { + content:"\e023"; +} +.status.status-finishing:after { + content:"\e027"; +} +.status.status-exception { + color: #a94442; +} +.status.status-exception:after { + content:"\e101"; +} + +#chart { + padding-top: 20px; +} + .btn-file { position: relative; overflow: hidden; diff --git a/WebCms/Controllers/ChartController.cs b/WebCms/Controllers/ChartController.cs new file mode 100644 index 0000000..d185499 --- /dev/null +++ b/WebCms/Controllers/ChartController.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Net; +using System.Web.Mvc; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.WebControls; +using log4net; +using LeafWeb.Core.Charter; +using LeafWeb.Core.Entities; +using LeafWeb.Core.Parsers; +using LeafWeb.Core.Utility; +using LeafWeb.WebCms.Models; +using LeafWeb.WebCms.Services; + +namespace LeafWeb.WebCms.Controllers +{ + public class ChartController : BaseController + { + public ActionResult Index(int? leafInputId) + { + if (!leafInputId.HasValue) + return View("DataError", model: "Must specify LeafInputId"); + + var leafOutputFile = DataService.GetLeafOutput_ChartFile(leafInputId.Value); + + if (leafOutputFile == null) + throw new ArgumentOutOfRangeException(); // TODO: break + + try + { + var curveIds = GetCurveIds(leafOutputFile.FileContents.Contents); + + var viewModel = new ChartViewModel + { + AvailableCurveId = curveIds, + LeafInputId = leafInputId.Value, + LeafInputIdentifier = leafOutputFile.LeafInput.Identifier + }; + + return View(viewModel); + } + catch (ParseException parseException) + { + var logger = LogManager.GetLogger(GetType()); + logger.Warn(parseException); + return View("DataError", model: parseException.Message); + } + catch (Exception e) + { + var logger = LogManager.GetLogger(GetType()); + logger.Warn(e); + return View("DataError", model: "Error while loading data. Administrators have been notified."); + } + } + + public ActionResult ChartCurve(int leafInputId, string curveId) + { + var leafOutputFile = DataService.GetLeafOutput_ChartFile(leafInputId); + + if (leafOutputFile == null) + throw new ArgumentOutOfRangeException(); // TODO: break + + CurveData curveData; + try + { + curveData = GetCurveData(leafOutputFile.FileContents.Contents, curveId); + } + catch (ParseException e) + { + return new HttpStatusCodeResult(HttpStatusCode.NotFound, e.Message); + } + catch (Exception) + { + return new HttpStatusCodeResult(HttpStatusCode.NotFound); + } + + if (curveData == null) + return new HttpStatusCodeResult(HttpStatusCode.NotFound); + + var charts = GetChartBitmaps(curveData).ToList(); + + var combinedChart = CombineBitmaps(charts); + + foreach (var chart in charts) chart.Dispose(); // cleanup + + using (var ms = new MemoryStream()) + { + combinedChart.Save(ms, ImageFormat.Png); + ms.Seek(0, SeekOrigin.Begin); + return File(ms.ToArray(), "image/png", curveId.FilterValidFilename() + ".png"); + } + } + + private CurveData GetCurveData(byte[] fileContents, string curveId) + { + try + { + LeafGasComparison[] leafGasComparisons; + using (var parser = new LeafGasComparisonParser(fileContents)) + leafGasComparisons = parser.Parse(curveId); + return CurveDataConverter.Convert(leafGasComparisons).First(); + } + catch (Exception e) + { + LogManager.GetLogger(GetType()).Warn(e); + throw; + } + return null; + } + + private string[] GetCurveIds(byte[] fileContents) + { + using (var parser = new LeafGasComparisonParser(fileContents)) + return parser.ExtractCurveIds(); + } + + private IEnumerable GetChartBitmaps(CurveData curveData) + { + var charts = LeafGasCharter.ProduceCharts(curveData); + + foreach (var chart in charts) + { + // http://stackoverflow.com/a/336396/99492 + var ms = new MemoryStream(); // this gets attached to the bmp, dispose of it later + chart.SaveImage(ms, ChartImageFormat.Bmp); + ms.Seek(0, SeekOrigin.Begin); + yield return new Bitmap(ms); + } + } + + private Bitmap CombineBitmaps(IList bitmaps, int columnCount = 2) + { + if (!bitmaps.Any()) + return null; + // bitmaps assumed to have same dimensions, use the first one to define that + var cellWidth = bitmaps[0].Width; + var cellHeight = bitmaps[0].Height; + var width = cellWidth * columnCount; + var height = cellHeight * bitmaps.Count / columnCount; + + var combinedBitmap = new Bitmap(width, height); + using (var g = Graphics.FromImage(combinedBitmap)) + { + var currentCol = 0; + var currentRow = 0; + foreach (var image in bitmaps) + { + g.DrawImage(image, currentCol * cellWidth, currentRow * cellHeight); + + currentCol = (currentCol + 1)%columnCount; + currentRow += currentCol == 0 ? 1 : 0; + } + } + return combinedBitmap; + } + + public ActionResult ChartSample() + { + var chart = new Chart + { + BackColor = Color.FromArgb(255, 255, 255), + Width = Unit.Pixel(250), + Height = Unit.Pixel(2500) + }; + + var series = new Series + { + ChartArea = "ca1", + ChartType = SeriesChartType.Line + }; + + //series.Font = new Font("Verdana", 8.25f, FontStyle.Regular); + + var myRandom = new Random(); + + for (int i = 0; i < 100; i++) + { + var dp = new DataPoint(); + dp.AxisLabel = String.Format("{0}-{1}", i, Guid.NewGuid().ToString().Substring(0, 4)); + dp.YValues = new double[] { myRandom.Next(5, 100) }; + series.Points.Add(dp); + } + + + chart.Series.Add(series); + + var area = new ChartArea("ca1"); + area.Area3DStyle.Enable3D = false; + area.AxisX.Interval = 1; + //area.BackColor = Color.Transparent; + //var labelStyle = new LabelStyle(); + //labelStyle.Enabled = true; + //labelStyle.Font = new Font("Arial", 3f); + area.AxisX.LabelStyle.Font = new Font("Verdana", 8.25f, FontStyle.Underline);//Why does it recognize the style but not the font!!!??? + + chart.ChartAreas.Add(area); + + using (var ms = new MemoryStream()) + { + chart.SaveImage(ms, ChartImageFormat.Png); + ms.Seek(0, SeekOrigin.Begin); + + return File(ms.ToArray(), "image/png", "mychart.png"); + } + } + } +} \ No newline at end of file diff --git a/WebCms/Controllers/FluxnetSiteController.cs b/WebCms/Controllers/FluxnetSiteController.cs index ace0a34..2b5b64d 100644 --- a/WebCms/Controllers/FluxnetSiteController.cs +++ b/WebCms/Controllers/FluxnetSiteController.cs @@ -7,7 +7,7 @@ namespace LeafWeb.WebCms.Controllers { public JsonResult Autocomplete(string query) { - var sites = DataService.GetFluxnetSitesAutocomplete(query).Take(50).ToList(); + var sites = DataService.GetFluxnetSitesAutocomplete(query).Take(40).ToList(); var data = new { suggestions = diff --git a/WebCms/Controllers/QueueController.cs b/WebCms/Controllers/QueueController.cs new file mode 100644 index 0000000..37bb88c --- /dev/null +++ b/WebCms/Controllers/QueueController.cs @@ -0,0 +1,95 @@ +using System.Linq; +using System.Web.Mvc; +using LeafWeb.Core.Entities; +using LeafWeb.Core.Utility; +using LeafWeb.WebCms.Models; + +namespace LeafWeb.WebCms.Controllers +{ + public class QueueController : BaseController + { + public ActionResult Index() + { + var viewModel = + DataService.GetLeafInputs() + .OrderByDescending(f => f.Id) + .ToList() + .Select(leafInput => new ResultStatusViewModel(leafInput)); + return View(viewModel); + } + + public ActionResult Details(int id) + { + var leafInput = DataService.GetLeafInput(id); + var viewModel = new LeafInputCreate(); + return View(viewModel); + } + + public ActionResult DownloadInput(int id) + { + return GetInputZip(id); + } + + public ActionResult DownloadOutputToUser(int id) + { + return GetOutputZip(id, LeafOutputFileType.ToUser); + } + + public ActionResult DownloadOutputNotToUser(int id) + { + return GetOutputZip(id, LeafOutputFileType.NotToUser); + } + + public ActionResult DownloadOutputCleanedInput(int id) + { + return GetOutputZip(id, LeafOutputFileType.CleanedInput); + } + + private ActionResult GetOutputZip(int id, LeafOutputFileType type) + { + var leafInput = DataService.GetLeafInput(id); + + if (leafInput == null) + return View("DownloadNotFound"); + + var zip = leafInput.GetOutputFileZip(type); + + var filename = $"{leafInput.Identifier.FilterValidFilename()}_{type}.zip"; + + return new FileContentResult(zip, "application/zip") { FileDownloadName = filename }; + } + + private ActionResult GetInputZip(int id) + { + var leafInput = DataService.GetLeafInput(id); + + if (leafInput == null) + return View("DownloadNotFound"); + + var zip = leafInput.GetInputFileZip(); + + var filename = $"{leafInput.Identifier.FilterValidFilename()}_Input.zip"; + + return new FileContentResult(zip, "application/zip") { FileDownloadName = filename }; + } + + 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); + DataService.DeleteLeafInput(leafInput); + + SetStatusMessage($"LeafInput '{leafInput.Identifier}' deleted"); + return RedirectToAction("Index"); + } + } +} \ No newline at end of file diff --git a/WebCms/Models/ChartViewModel.cs b/WebCms/Models/ChartViewModel.cs new file mode 100644 index 0000000..218219d --- /dev/null +++ b/WebCms/Models/ChartViewModel.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace LeafWeb.WebCms.Models +{ + public class ChartViewModel + { + public int LeafInputId { get; set; } + public string CurveId { get; set; } + public IEnumerable AvailableCurveId { get; set; } + public string LeafInputIdentifier { get; set; } + } + + public class ChartQueryViewModel + { + public int LeafInputId { get; set; } + public string CurveId { get; set; } + } +} \ No newline at end of file diff --git a/WebCms/Views/BlogOverview.cshtml b/WebCms/Views/BlogOverview.cshtml index a1aa5c7..4ab61dd 100644 --- a/WebCms/Views/BlogOverview.cshtml +++ b/WebCms/Views/BlogOverview.cshtml @@ -8,20 +8,24 @@
- +
+ @if (!CurrentPage.Children.Any()) + { +
No news items to display.
+} + @foreach (var post in CurrentPage.Children) + { + + } +
diff --git a/WebCms/Views/Chart/DataError.cshtml b/WebCms/Views/Chart/DataError.cshtml new file mode 100644 index 0000000..8016d29 --- /dev/null +++ b/WebCms/Views/Chart/DataError.cshtml @@ -0,0 +1,4 @@ +@model string + +

There was an issue generating a chart for the selected data.

+

Details: @Model

\ No newline at end of file diff --git a/WebCms/Views/Chart/Index.cshtml b/WebCms/Views/Chart/Index.cshtml new file mode 100644 index 0000000..0b539f5 --- /dev/null +++ b/WebCms/Views/Chart/Index.cshtml @@ -0,0 +1,20 @@ +@model LeafWeb.WebCms.Models.ChartViewModel +@{ + var selectText = "Select CurveId"; +} + +
+
+
Identifier: @Model.LeafInputIdentifier +
+
+
+ CurveId: + @Html.DropDownList("CurveId", new SelectList(Model.AvailableCurveId, Model.CurveId), selectText) +
+
+ + + + + diff --git a/WebCms/Views/Home.cshtml b/WebCms/Views/Home.cshtml index 39d51c4..7b7dcd5 100644 --- a/WebCms/Views/Home.cshtml +++ b/WebCms/Views/Home.cshtml @@ -4,30 +4,4 @@ }
@CurrentPage.GetGridHtml("content", "fanoe") -
-@{ - var blogSelection = CurrentPage.Site().FirstChild("BlogPostRepository").Children("BlogPost").Where("Visible"); -} -
- -
- -
-
\ No newline at end of file diff --git a/WebCms/Views/LeafInput/Create.cshtml b/WebCms/Views/LeafInput/Create.cshtml index 484479c..0dd1f6e 100644 --- a/WebCms/Views/LeafInput/Create.cshtml +++ b/WebCms/Views/LeafInput/Create.cshtml @@ -21,7 +21,7 @@
- Select all + Select all + @Html.HiddenFor(m => loginModel.RedirectUrl) + + } +
+ + \ No newline at end of file diff --git a/WebCms/Views/MacroPartials/Queue.cshtml b/WebCms/Views/MacroPartials/Queue.cshtml new file mode 100644 index 0000000..54368f1 --- /dev/null +++ b/WebCms/Views/MacroPartials/Queue.cshtml @@ -0,0 +1,5 @@ +@inherits Umbraco.Web.Macros.PartialViewMacroPage + +@{ + Html.RenderAction("Index", "Queue"); +} \ No newline at end of file diff --git a/WebCms/Views/Master.cshtml b/WebCms/Views/Master.cshtml index 64a80c8..f802b6c 100644 --- a/WebCms/Views/Master.cshtml +++ b/WebCms/Views/Master.cshtml @@ -1,7 +1,18 @@ -@inherits UmbracoTemplatePage +@using ClientDependency.Core.Mvc +@inherits UmbracoTemplatePage @{ Layout = null; - var home = CurrentPage.Site(); + var home = CurrentPage.Site(); + if (TempData.ContainsKey("LoginSuccess") && (bool)TempData["LoginSuccess"]) + { + TempData["StatusMessage"] = "Welcome " + Members.GetCurrentLoginStatus().Name; + TempData["StatusMessage-Type"] = "alert-success"; + } + else if (TempData.ContainsKey("LogoutSuccess") && (bool)TempData["LogoutSuccess"]) + { + TempData["StatusMessage"] = "Logout sucessful"; + TempData["StatusMessage-Type"] = "alert-success"; + } } @@ -23,7 +34,8 @@ - + + @Html.RenderJsHere() @RenderSection("Styles", false) @@ -66,7 +78,7 @@
- @*@{ Html.RenderPartial("BottomNavigation"); }*@ + @{ Html.RenderPartial("BottomNavigation"); }
diff --git a/WebCms/Views/Partials/BottomNavigation.cshtml b/WebCms/Views/Partials/BottomNavigation.cshtml index b78c6a6..7923bbb 100644 --- a/WebCms/Views/Partials/BottomNavigation.cshtml +++ b/WebCms/Views/Partials/BottomNavigation.cshtml @@ -1,11 +1,20 @@ -@inherits Umbraco.Web.Mvc.UmbracoTemplatePage +@inherits UmbracoTemplatePage @{ var home = CurrentPage.Site(); } -@if (home.Children.Where("Visible").Any()) +
+ User +
    +
  • + @Html.Partial("LoginStatus") +
  • +
+
+ + +@*@if (home.Children.Where("Visible").Any()) { - @* For each child page under the home node, where the property umbracoNaviHide is not True *@ foreach (var childPage in home.Children.Where("Visible")) {
@@ -16,22 +25,8 @@ }
} -} +}*@ -
- Find us - -
@helper childPages(dynamic pages) { diff --git a/WebCms/Views/Partials/LoginStatus.cshtml b/WebCms/Views/Partials/LoginStatus.cshtml new file mode 100644 index 0000000..05f63df --- /dev/null +++ b/WebCms/Views/Partials/LoginStatus.cshtml @@ -0,0 +1,35 @@ +@inherits UmbracoTemplatePage +@using System.Web.Mvc.Html +@using ClientDependency.Core.Mvc +@using Umbraco.Web +@using Umbraco.Web.Models +@using Umbraco.Web.Controllers +@{ + var loginStatusModel = Members.GetCurrentLoginStatus(); + + Html.EnableClientValidation(); + Html.EnableUnobtrusiveJavaScript(); + Html.RequiresJs("/umbraco_client/ui/jquery.js"); + Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js"); + Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js"); + + var logoutModel = new PostRedirectModel { RedirectUrl = "/" }; +} +@if (loginStatusModel.IsLoggedIn) +{ +
+
@loginStatusModel.Name
+
+ + @using (Html.BeginUmbracoForm("HandleLogout")) + { + + @Html.HiddenFor(m => logoutModel.RedirectUrl) + } +
+
+} +else +{ + Login +} \ No newline at end of file diff --git a/WebCms/Views/Partials/MainNavigation.cshtml b/WebCms/Views/Partials/MainNavigation.cshtml index bcd37af..4786dee 100644 --- a/WebCms/Views/Partials/MainNavigation.cshtml +++ b/WebCms/Views/Partials/MainNavigation.cshtml @@ -1,4 +1,4 @@ -@inherits Umbraco.Web.Mvc.UmbracoTemplatePage +@inherits UmbracoTemplatePage @{ var home = CurrentPage.Site(); } @if (home.Children.Any()) @@ -9,10 +9,10 @@ @* Add in level for a CSS hook *@
    @* For each child page under the home node *@ - @foreach (var childPage in home.Children) - { - if (childPage.Children.Any()) - { + @foreach (var childPage in home.Children.Where("Visible")) + { + if (childPage.Children.Where("Visible").Any()) + {
  • @if(childPage.DocumentTypeAlias == "LandingPage") { @@ -36,20 +36,26 @@ @helper childPages(dynamic pages) { @* Ensure that we have a collection of pages *@ - if (pages.Any()) + if (pages.Where("Visible").Any()) { @* Get the first page in pages and get the level *@ var naviLevel = pages.First().Level; @* Add in level for a CSS hook *@
      - @foreach (var page in pages) + @foreach (var page in pages.Where("Visible")) { + if (library.IsProtected(page.id, page.path) + && !library.HasAccess(page.id, page.path)) + { + continue; + } +
    • @page.Name @* if the current page has any children *@ - @if (page.Children.Any()) + @if (page.Children.Where("Visible").Any()) { @* Call our helper to display the children *@ @childPages(page.Children) @@ -58,4 +64,4 @@ }
    } -} \ No newline at end of file +} diff --git a/WebCms/Views/Queue/Details.cshtml b/WebCms/Views/Queue/Details.cshtml new file mode 100644 index 0000000..2e38b4c --- /dev/null +++ b/WebCms/Views/Queue/Details.cshtml @@ -0,0 +1,3 @@ +@model LeafWeb.WebCms.Models.LeafInputCreate + +@Html.DisplayForModel() diff --git a/WebCms/Views/Queue/DownloadNotFound.cshtml b/WebCms/Views/Queue/DownloadNotFound.cshtml new file mode 100644 index 0000000..031fe62 --- /dev/null +++ b/WebCms/Views/Queue/DownloadNotFound.cshtml @@ -0,0 +1,10 @@ +@{ + ViewBag.Title = "Not Found"; +} + +

    + @ViewBag.Title +

    + +

    The given download link was not found. Please contact administrator, referencing the following url:

    +@Html.Raw(Request.Url) \ No newline at end of file diff --git a/WebCms/Views/Queue/Index.cshtml b/WebCms/Views/Queue/Index.cshtml new file mode 100644 index 0000000..ae4e231 --- /dev/null +++ b/WebCms/Views/Queue/Index.cshtml @@ -0,0 +1,49 @@ +@model IEnumerable + +@{ + var grid = new WebGrid(Model, rowsPerPage: 45); +} + +@grid.GetHtml(columns: + grid.Columns( + grid.Column("LeafInputIdentifier", "Identifier"), + grid.Column("LeafInputSiteId", "Site Id"), + grid.Column("LeafInputName", "Submitted By"), + grid.Column("CurrentStatus", "Status", item => statusFormat(item)), + grid.Column("Chart", "Chart", item => chartLink(item)), + grid.Column("Total Results: " + Model.Count(), format: item => btns(item))), + htmlAttributes: new { @class = "table table-striped table-bordered table-hover table-condensed" } + ) + +@helper btns(dynamic item) +{ +
    + @Html.ActionLink("Details", "Details", new { id = item.LeafInputId }, new { @class = "btn btn-default btn-xs", role = "button" }) +
    + + +
    + + @Html.ActionLink("Delete", "Delete", new { id = item.LeafInputId }, new { @class = "btn btn-default btn-xs", role = "button" }) +
    +} + + +@helper chartLink(dynamic item) +{ +if (item.HasLeafChart) +{ + Chart +} +} + +@helper statusFormat(dynamic item) +{ + @item.CurrentStatus +} \ No newline at end of file diff --git a/WebCms/Views/Results/Index.cshtml b/WebCms/Views/Results/Index.cshtml index d4efb07..0e7ed90 100644 --- a/WebCms/Views/Results/Index.cshtml +++ b/WebCms/Views/Results/Index.cshtml @@ -9,11 +9,21 @@ grid.Column("LeafInputIdentifier", "Identifier"), grid.Column("LeafInputSiteId", "Site Id"), grid.Column("LeafInputName", "Submitted By"), - grid.Column("CurrentStatus", "Status"), - grid.Column("Chart", "Chart", item => - item.HasLeafChart - ? Html.ActionLink("Chart", "Index", "Chart", new {leafInputId = item.LeafInputId}, new {}) - : Html.Raw("")) + grid.Column("CurrentStatus", "Status", item => statusFormat(item)), + grid.Column("Chart", "Chart", item => chartLink(item)) ), htmlAttributes: new { @class = "table table-striped table-bordered table-hover table-condensed" } ) + +@helper chartLink(dynamic item) +{ +if (item.HasLeafChart) +{ + Chart +} +} + +@helper statusFormat(dynamic item) +{ + @item.CurrentStatus +} \ No newline at end of file diff --git a/WebCms/Views/Shared/_StatusMessage.cshtml b/WebCms/Views/Shared/_StatusMessage.cshtml index ab19134..614d72b 100644 --- a/WebCms/Views/Shared/_StatusMessage.cshtml +++ b/WebCms/Views/Shared/_StatusMessage.cshtml @@ -11,4 +11,4 @@ else if (ViewBag.StatusMessage != null) @ViewBag.StatusMessage

    -} +} \ No newline at end of file diff --git a/WebCms/Views/TextPage.cshtml b/WebCms/Views/TextPage.cshtml index 7d7d0bb..b158b37 100644 --- a/WebCms/Views/TextPage.cshtml +++ b/WebCms/Views/TextPage.cshtml @@ -3,6 +3,7 @@ Layout = "Master.cshtml"; var leafInputBackload = GetBoolProperty(Model.Content.Properties, "leafInputBackload"); + var chart = GetBoolProperty(Model.Content.Properties, "chart"); } @section Styles @@ -10,7 +11,9 @@ @if (leafInputBackload) { @Styles.Render("~/backload/blueimp/bootstrap/BasicPlusUI/css") } } -@CurrentPage.GetGridHtml("content", "fanoe") +
    + @CurrentPage.GetGridHtml("content", "fanoe") +
    @section Scripts { @@ -18,6 +21,7 @@ @if (leafInputBackload) { @Scripts.Render("~/backload/blueimp/bootstrap/BasicPlusUI") } @if (leafInputBackload) { } + @if (chart) { } @if (leafInputBackload) { diff --git a/WebCms/WebCms.csproj b/WebCms/WebCms.csproj index 257b47b..515e881 100644 --- a/WebCms/WebCms.csproj +++ b/WebCms/WebCms.csproj @@ -619,6 +619,7 @@ + @@ -690,6 +691,17 @@ + + + + + + + + + + + Web.config @@ -740,9 +752,12 @@ + + + diff --git a/WebCms/scripts/Chart.js b/WebCms/scripts/Chart.js new file mode 100644 index 0000000..3b17875 --- /dev/null +++ b/WebCms/scripts/Chart.js @@ -0,0 +1,42 @@ +var getUrlParameter = function getUrlParameter(sParam) { + var sPageURL = decodeURIComponent(window.location.search.substring(1)), + sURLVariables = sPageURL.split('&'), + sParameterName, + i; + + for (i = 0; i < sURLVariables.length; i++) { + sParameterName = sURLVariables[i].split('='); + + if (sParameterName[0] === sParam) { + return sParameterName[1] === undefined ? true : sParameterName[1]; + } + } +}; + +$(function () { + var baseUrl = "/umbraco/surface/Chart/ChartCurve"; + $('#CurveId') + .change(function () { + $('#chart-error').removeClass('text-danger').text(''); + var $chart = $("#chart"); + $chart.removeAttr('src'); + + var curveId = $("option:selected", this).text(); + if (curveId === "@Html.Raw(selectText)") { + return; + } + var $spinner = $(this).after('').next('i'); + + var leafInputId = getUrlParameter("leafInputId"); + var url = baseUrl + "?leafInputId=" + leafInputId + "&curveId=" + curveId; + $chart.load(function () { + $spinner.remove(); + }) + .error(function () { + $chart.removeAttr('src'); + $spinner.remove(); + $('#chart-error').addClass('text-danger').text('A problem was encountered loading this chart.'); + }) + .attr('src', url); + }); +}); \ No newline at end of file