Charts, login, manage queue, styling

This commit is contained in:
2016-12-08 12:15:47 -05:00
parent 6fd7e46f5d
commit a29de1ecb8
30 changed files with 808 additions and 90 deletions
+20 -2
View File
@@ -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
}
///<summary>
/// Hide in bottom navigation?
/// Hide in navigation?
///</summary>
[ImplementPropertyType("umbracoNaviHide")]
public bool UmbracoNaviHide
@@ -250,6 +250,15 @@ namespace Umbraco.Web.PublishedContentModels
return PublishedContentModelUtility.GetModelPropertyType(GetModelContentType(), selector);
}
///<summary>
/// Chart: loads scripts for charting
///</summary>
[ImplementPropertyType("chart")]
public bool Chart
{
get { return this.GetPropertyValue<bool>("chart"); }
}
///<summary>
/// Content
///</summary>
@@ -267,6 +276,15 @@ namespace Umbraco.Web.PublishedContentModels
{
get { return this.GetPropertyValue<bool>("leafInputBackload"); }
}
///<summary>
/// Hide in Navigation?
///</summary>
[ImplementPropertyType("umbracoNaviHide")]
public bool UmbracoNaviHide
{
get { return this.GetPropertyValue<bool>("umbracoNaviHide"); }
}
}
/// <summary>Folder</summary>
+21 -3
View File
@@ -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
}
///<summary>
/// Hide in bottom navigation?
/// Hide in navigation?
///</summary>
[ImplementPropertyType("umbracoNaviHide")]
public bool UmbracoNaviHide
@@ -234,6 +234,15 @@ namespace Umbraco.Web.PublishedContentModels
return PublishedContentModelUtility.GetModelPropertyType(GetModelContentType(), selector);
}
///<summary>
/// Chart: loads scripts for charting
///</summary>
[ImplementPropertyType("chart")]
public bool Chart
{
get { return this.GetPropertyValue<bool>("chart"); }
}
///<summary>
/// Content
///</summary>
@@ -251,6 +260,15 @@ namespace Umbraco.Web.PublishedContentModels
{
get { return this.GetPropertyValue<bool>("leafInputBackload"); }
}
///<summary>
/// Hide in Navigation?
///</summary>
[ImplementPropertyType("umbracoNaviHide")]
public bool UmbracoNaviHide
{
get { return this.GetPropertyValue<bool>("umbracoNaviHide"); }
}
}
/// <summary>Folder</summary>
+1 -1
View File
@@ -1 +1 @@
9bd3b2ce6fad5710
72e45477d4ceda7e
+89 -4
View File
@@ -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;
+211
View File
@@ -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<Bitmap> 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<Bitmap> 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");
}
}
}
}
+1 -1
View File
@@ -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 =
+95
View File
@@ -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");
}
}
}
+18
View File
@@ -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<string> AvailableCurveId { get; set; }
public string LeafInputIdentifier { get; set; }
}
public class ChartQueryViewModel
{
public int LeafInputId { get; set; }
public string CurveId { get; set; }
}
}
+5 -1
View File
@@ -9,7 +9,11 @@
<div class="container">
<div class="row">
@foreach(var post in CurrentPage.Children)
@if (!CurrentPage.Children.Any())
{
<div>No news items to display.</div>
}
@foreach (var post in CurrentPage.Children)
{
<div class="col-sm-6">
<div class="content equal">
+4
View File
@@ -0,0 +1,4 @@
@model string
<p><strong>There was an issue generating a chart for the selected data.</strong></p>
<p><strong>Details:</strong> @Model</p>
+20
View File
@@ -0,0 +1,20 @@
@model LeafWeb.WebCms.Models.ChartViewModel
@{
var selectText = "Select CurveId";
}
<div class="row">
<div class="col-sm-4">
<div>Identifier: <strong>@Model.LeafInputIdentifier</strong>
</div>
</div>
<div class="col-sm-8">
<span>CurveId:</span>
@Html.DropDownList("CurveId", new SelectList(Model.AvailableCurveId, Model.CurveId), selectText)
</div>
</div>
<img id="chart"/>
<span class="help-block">
<span id="chart-error"></span>
</span>
-26
View File
@@ -5,29 +5,3 @@
<div class="home">
@CurrentPage.GetGridHtml("content", "fanoe")
</div>
@{
var blogSelection = CurrentPage.Site().FirstChild("BlogPostRepository").Children("BlogPost").Where("Visible");
}
<div role="content">
<section class="light blogarchive equalizer">
<div class="container">
<div class="row">
@foreach(var post in blogSelection)
{
<div class="col-sm-6">
<div class="content equal">
<a href="@post.Url">
<div class="date">@post.CreateDate.ToLongDateString()</div>
<h2>@post.Name</h2>
<p>@Umbraco.Truncate(post.Introduction, 240, true)</p>
</a>
</div>
</div>
}
</div>
</div>
</section>
</div>
+1 -1
View File
@@ -21,7 +21,7 @@
<span class="fileupload-process"></span>
</div>
<div class="col-lg-6 pull-right">
<span class="pull-right"> Select all <input type="checkbox" class="toggle"></span>
<span class="pull-right" style="margin-left: 10px;"> Select all <input type="checkbox" class="toggle"></span>
<button type="button" class="btn btn-default delete pull-right">
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
@@ -0,0 +1,11 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
var link = Model.MacroParameters["Link"];
var title = Model.MacroParameters["Title"];
var description = Model.MacroParameters["Description"];
var glyphicon = Model.MacroParameters["Glyphicon"];
}
<a class="banner-link" href="@link">
<h2>@title <span class="glyphicon @glyphicon"></span></h2>
<p>@description</p>
</a>
@@ -0,0 +1,28 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
var blogSelection = CurrentPage.Site().FirstChild("BlogPostRepository").Children("BlogPost").Where("Visible");
}
<div role="content">
<section class="light blogarchive equalizer">
<div class="container">
<div class="row">
@if (!blogSelection.Any())
{
<div>No news items to display.</div>
}
@foreach (var post in blogSelection)
{
<div class="col-sm-6">
<div class="content equal">
<a href="@post.Url">
<div class="date">@post.CreateDate.ToLongDateString()</div>
<h2>@post.Name</h2>
<p>@Umbraco.Truncate(post.Introduction, 240, true)</p>
</a>
</div>
</div>
}
</div>
</div>
</section>
</div>
+5
View File
@@ -0,0 +1,5 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
Html.RenderAction("Index", "Chart");
}
@@ -0,0 +1,41 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@using System.Web.Mvc.Html
@using ClientDependency.Core.Mvc
@using Umbraco.Web
@using Umbraco.Web.Models
@using Umbraco.Web.Controllers
@{
var loginModel = new LoginModel { RedirectUrl = "/leaf-data/manage-queue/" };
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");
}
<div class="container">
<div class="row">
<div class="col-md-7 well">
@using (Html.BeginUmbracoForm<UmbLoginController>("HandleLogin"))
{
<fieldset>
@Html.ValidationSummary("loginModel", true)
<div class="form-group">
@Html.LabelFor(m => loginModel.Username, new { @class = "control-label" })
@Html.TextBoxFor(m => loginModel.Username)
@Html.ValidationMessageFor(m => loginModel.Username)
</div>
<div class="form-group">
@Html.LabelFor(m => loginModel.Password, new { @class = "control-label" })
@Html.PasswordFor(m => loginModel.Password)
@Html.ValidationMessageFor(m => loginModel.Password)
</div>
<button class="btn btn-primary pull-right">Login</button>
@Html.HiddenFor(m => loginModel.RedirectUrl)
</fieldset>
}
</div>
</div>
</div>
+5
View File
@@ -0,0 +1,5 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
Html.RenderAction("Index", "Queue");
}
+15 -3
View File
@@ -1,7 +1,18 @@
@inherits UmbracoTemplatePage
@using ClientDependency.Core.Mvc
@inherits UmbracoTemplatePage
@{
Layout = null;
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";
}
}
<!DOCTYPE html>
@@ -23,7 +34,8 @@
<!-- CSS -->
<link href="~/Content/bootstrap.min.css" type="text/css" rel="stylesheet" />
<link href="~/Content/site.css" type="text/css" rel="stylesheet" />
<link href="~/Content/style.css" type="text/css" rel="stylesheet" />
<link href="~/Content/style.css" type="text/css" rel="stylesheet"/>
@Html.RenderJsHere()
@RenderSection("Styles", false)
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
@@ -66,7 +78,7 @@
<div class="container">
<div class="row">
@*@{ Html.RenderPartial("BottomNavigation"); }*@
@{ Html.RenderPartial("BottomNavigation"); }
</div>
</div>
+13 -18
View File
@@ -1,11 +1,20 @@
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@inherits UmbracoTemplatePage
@{
var home = CurrentPage.Site();
}
@if (home.Children.Where("Visible").Any())
<div class="col-xs-6 col-sm-3">
<strong>User</strong>
<ul>
<li>
@Html.Partial("LoginStatus")
</li>
</ul>
</div>
@*@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"))
{
<div class="col-xs-6 col-sm-3">
@@ -16,22 +25,8 @@
}
</div>
}
}
}*@
<div class="col-xs-6 col-sm-3">
<strong>Find us</strong>
<ul>
<li>
<a href="https://twitter.com/umbracoproject" target="_blank">Twitter</a>
</li>
<li>
<a href="https://www.facebook.com/Umbraco" target="_blank">Facebook</a>
</li>
<li>
<a href="http://umbraco.com/?utm_source=core&utm_medium=starterkit&utm_content=topic-link&utm_campaign=fanoe" target="_blank">Umbraco.com</a>
</li>
</ul>
</div>
@helper childPages(dynamic pages)
{
+35
View File
@@ -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)
{
<div class="row">
<div class="">@loginStatusModel.Name</div>
<div class="">
@using (Html.BeginUmbracoForm<UmbLoginStatusController>("HandleLogout"))
{
<button href="#" class="btn btn-primary btn-xs">Logout</button>
@Html.HiddenFor(m => logoutModel.RedirectUrl)
}
</div>
</div>
}
else
{
<a href="/membership/login">Login</a>
}
+12 -6
View File
@@ -1,4 +1,4 @@
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@inherits UmbracoTemplatePage
@{ var home = CurrentPage.Site(); }
@if (home.Children.Any())
@@ -9,9 +9,9 @@
@* Add in level for a CSS hook *@
<ul class="level-@naviLevel">
@* For each child page under the home node *@
@foreach (var childPage in home.Children)
@foreach (var childPage in home.Children.Where("Visible"))
{
if (childPage.Children.Any())
if (childPage.Children.Where("Visible").Any())
{
<li class="has-child @(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null)">
@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 *@
<ul class="sublevel level-@(naviLevel)">
@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;
}
<li>
<a href="@page.Url">@page.Name</a>
@* 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)
+3
View File
@@ -0,0 +1,3 @@
@model LeafWeb.WebCms.Models.LeafInputCreate
@Html.DisplayForModel()
@@ -0,0 +1,10 @@
@{
ViewBag.Title = "Not Found";
}
<h1>
@ViewBag.Title
</h1>
<p>The given download link was not found. Please contact administrator, referencing the following url:</p>
<code>@Html.Raw(Request.Url)</code>
+49
View File
@@ -0,0 +1,49 @@
@model IEnumerable<LeafWeb.WebCms.Models.ResultStatusViewModel>
@{
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)
{
<div class="btn-group" role="group">
@Html.ActionLink("Details", "Details", new { id = item.LeafInputId }, new { @class = "btn btn-default btn-xs", role = "button" })
<div class="btn-group" role="group">
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Download
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>@Html.ActionLink("ToUser", "DownloadOutputToUser", new { id = item.LeafInputId })</li>
<li>@Html.ActionLink("Input", "DownloadInput", new { id = item.LeafInputId })</li>
</ul>
</div>
@Html.ActionLink("Delete", "Delete", new { id = item.LeafInputId }, new { @class = "btn btn-default btn-xs", role = "button" })
</div>
}
@helper chartLink(dynamic item)
{
if (item.HasLeafChart)
{
<a href="@UmbracoContext.Current.UrlProvider.GetUrl(1100)?leafInputId=@item.LeafInputId">Chart</a>
}
}
@helper statusFormat(dynamic item)
{
<span class="status status-@item.CurrentStatus.ToLower()">@item.CurrentStatus</span>
}
+15 -5
View File
@@ -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)
{
<a href="@UmbracoContext.Current.UrlProvider.GetUrl(1100)?leafInputId=@item.LeafInputId">Chart</a>
}
}
@helper statusFormat(dynamic item)
{
<span class="status status-@item.CurrentStatus.ToLower()">@item.CurrentStatus</span>
}
+5 -1
View File
@@ -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")
<div role="content">
@CurrentPage.GetGridHtml("content", "fanoe")
</div>
@section Scripts
{
@@ -18,6 +21,7 @@
@if (leafInputBackload) { @Scripts.Render("~/backload/blueimp/bootstrap/BasicPlusUI") }
<!-- jQuery autocomplete* -->
@if (leafInputBackload) { <script src="~/scripts/jquery.autocomplete.min.js"></script> }
@if (chart) { <script src="~/scripts/Chart.js"></script> }
@if (leafInputBackload)
{
+15
View File
@@ -619,6 +619,7 @@
<Content Include="scripts\bootstrap.js" />
<Content Include="scripts\bootstrap.min.js" />
<None Include="scripts\jquery-1.11.1.intellisense.js" />
<Content Include="scripts\Chart.js" />
<Content Include="scripts\jquery-1.11.1.js" />
<Content Include="scripts\jquery-1.11.1.min.js" />
<Content Include="scripts\jquery.autocomplete.js" />
@@ -690,6 +691,17 @@
<Content Include="Views\Results\DownloadNotFound.cshtml" />
<Content Include="Views\Results\Index.cshtml" />
<Content Include="Views\MacroPartials\Results.cshtml" />
<Content Include="Views\Chart\DataError.cshtml" />
<Content Include="Views\Chart\Index.cshtml" />
<Content Include="Views\MacroPartials\Chart.cshtml" />
<Content Include="Views\MacroPartials\BannerLink.cshtml" />
<Content Include="Views\MacroPartials\Membership\Login.cshtml" />
<Content Include="Views\Queue\Index.cshtml" />
<Content Include="Views\Queue\DownloadNotFound.cshtml" />
<Content Include="Views\Queue\Details.cshtml" />
<Content Include="Views\MacroPartials\BlogHighlights.cshtml" />
<Content Include="Views\MacroPartials\Queue.cshtml" />
<Content Include="Views\Partials\LoginStatus.cshtml" />
<None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</None>
@@ -740,9 +752,12 @@
<Compile Include="Controllers\ActionLogAttribute.cs" />
<Compile Include="Controllers\BackloadController.cs" />
<Compile Include="Controllers\BaseController.cs" />
<Compile Include="Controllers\ChartController.cs" />
<Compile Include="Controllers\FluxnetSiteController.cs" />
<Compile Include="Controllers\LeafInputController.cs" />
<Compile Include="Controllers\QueueController.cs" />
<Compile Include="Controllers\ResultsController.cs" />
<Compile Include="Models\ChartViewModel.cs" />
<Compile Include="Models\LeafInputCreate.cs" />
<Compile Include="Models\ResultStatusViewModel.cs" />
<Compile Include="Models\SelectListViewModel.cs" />
+42
View File
@@ -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('<i class="fa fa-spinner fa-spin"></i>').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);
});
});