Refresh Pt 5d

This commit is contained in:
Thomas Hounsell 2015-05-04 16:43:20 +01:00
parent 2650353aba
commit f070d2a5cd
9 changed files with 128 additions and 44 deletions

View File

@ -183,6 +183,7 @@
<Compile Include="Models\ApiModel\SearchResult.cs" /> <Compile Include="Models\ApiModel\SearchResult.cs" />
<Compile Include="Models\Build.cs" /> <Compile Include="Models\Build.cs" />
<Compile Include="Models\MetaItem.cs" /> <Compile Include="Models\MetaItem.cs" />
<Compile Include="Models\ViewModel\Front\FrontBuildGroup.cs" />
<Compile Include="Models\ViewModel\LoginUser.cs" /> <Compile Include="Models\ViewModel\LoginUser.cs" />
<Compile Include="Models\ViewModel\ChangePassword.cs" /> <Compile Include="Models\ViewModel\ChangePassword.cs" />
<Compile Include="Models\ViewModel\QuestionForm.cs" /> <Compile Include="Models\ViewModel\QuestionForm.cs" />
@ -313,7 +314,6 @@
<ItemGroup> <ItemGroup>
<Folder Include="App_Data\" /> <Folder Include="App_Data\" />
<Folder Include="Areas\admin\Views\Shared\" /> <Folder Include="Areas\admin\Views\Shared\" />
<Folder Include="Models\ViewModel\Front\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="packages.config"> <Content Include="packages.config">
@ -352,7 +352,7 @@
<AutoAssignPort>True</AutoAssignPort> <AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>50468</DevelopmentServerPort> <DevelopmentServerPort>50468</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath> <DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:50468/</IISUrl> <IISUrl>http://localhost:50505/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication> <NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer> <UseCustomServer>False</UseCustomServer>
<CustomServerUrl> <CustomServerUrl>

View File

@ -1,4 +1,5 @@
using BuildFeed.Models; using BuildFeed.Models;
using BuildFeed.Models.ViewModel.Front;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -10,13 +11,22 @@ namespace BuildFeed.Controllers
{ {
public class frontController : Controller public class frontController : Controller
{ {
private const int _pageSize = 25; private const int _pageSize = 84;
[Route("")] [Route("", Order = 1)]
#if !DEBUG #if !DEBUG
[OutputCache(Duration = 600, VaryByParam = "none")] [OutputCache(Duration = 600, VaryByParam = "none")]
#endif #endif
public ActionResult index() public ActionResult index()
{
return indexPage(1);
}
[Route("page-{page:int:min(2)}/", Order = 0)]
#if !DEBUG
[OutputCache(Duration = 600, VaryByParam = "none")]
#endif
public ActionResult indexPage(int page)
{ {
var buildGroups = from b in Build.Select() var buildGroups = from b in Build.Select()
group b by new BuildGroup() group b by new BuildGroup()
@ -30,8 +40,17 @@ public ActionResult index()
bg.Key.Minor descending, bg.Key.Minor descending,
bg.Key.Build descending, bg.Key.Build descending,
bg.Key.Revision descending bg.Key.Revision descending
select bg; select new FrontBuildGroup()
return View(buildGroups); {
Key = bg.Key,
LastBuild = bg.Max(m => m.BuildTime),
BuildCount = bg.Count()
};
ViewBag.PageNumber = page;
ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(buildGroups.Count()) / Convert.ToDouble(_pageSize));
return View("index", buildGroups.Skip((page - 1) * _pageSize).Take(_pageSize));
} }
[Route("group/{major}.{minor}.{number}.{revision}/")] [Route("group/{major}.{minor}.{number}.{revision}/")]

View File

@ -17,14 +17,13 @@ namespace BuildFeed.Controllers
{ {
public class supportController : Controller public class supportController : Controller
{ {
[Route("login")] [Route("login/")]
public ActionResult login() public ActionResult login()
{ {
return View(); return View();
} }
[HttpPost] [HttpPost, Route("login/")]
[Route("login")]
public ActionResult login(LoginUser ru) public ActionResult login(LoginUser ru)
{ {
if (ModelState.IsValid) if (ModelState.IsValid)
@ -51,15 +50,13 @@ public ActionResult login(LoginUser ru)
return View(ru); return View(ru);
} }
[Authorize] [Authorize, Route("password/")]
[Route("password")]
public ActionResult password() public ActionResult password()
{ {
return View(); return View();
} }
[HttpPost] [HttpPost, Authorize, Route("password/")]
[Route("password")]
public ActionResult password(ChangePassword cp) public ActionResult password(ChangePassword cp)
{ {
if (ModelState.IsValid) if (ModelState.IsValid)
@ -77,21 +74,20 @@ public ActionResult password(ChangePassword cp)
return View(cp); return View(cp);
} }
[Route("logout")] [Route("logout/")]
public ActionResult logout() public ActionResult logout()
{ {
FormsAuthentication.SignOut(); FormsAuthentication.SignOut();
return Redirect("/"); return Redirect("/");
} }
[Route("register")] [Route("register/")]
public ActionResult register() public ActionResult register()
{ {
return View(); return View();
} }
[HttpPost] [HttpPost, Route("register/")]
[Route("register")]
public ActionResult register(RegistrationUser ru) public ActionResult register(RegistrationUser ru)
{ {
if (ModelState.IsValid) if (ModelState.IsValid)
@ -121,7 +117,7 @@ public ActionResult register(RegistrationUser ru)
return View(ru); return View(ru);
} }
[Route("register")] [Route("register/")]
public ActionResult thanks_register() public ActionResult thanks_register()
{ {
return View(); return View();
@ -133,7 +129,7 @@ public ActionResult rss()
return View(); return View();
} }
[Route("sitemap")] [Route("sitemap/")]
#if !DEBUG #if !DEBUG
[OutputCache(Duration = 3600, VaryByParam = "none")] [OutputCache(Duration = 3600, VaryByParam = "none")]
#endif #endif
@ -235,7 +231,7 @@ orderby bv.Key
return View(model); return View(model);
} }
[Route("xml-sitemap")] [Route("xml-sitemap/")]
#if !DEBUG #if !DEBUG
[OutputCache(Duration = 3600, VaryByParam = "none")] [OutputCache(Duration = 3600, VaryByParam = "none")]
#endif #endif
@ -273,7 +269,7 @@ public ActionResult xmlsitemap()
return new EmptyResult(); return new EmptyResult();
} }
[Route("statistics")] [Route("statistics/")]
#if !DEBUG #if !DEBUG
[OutputCache(Duration = 3600, VaryByParam = "none")] [OutputCache(Duration = 3600, VaryByParam = "none")]
#endif #endif
@ -319,7 +315,7 @@ where b.BuildTime.HasValue
where !string.IsNullOrEmpty(b.Lab) where !string.IsNullOrEmpty(b.Lab)
group b by b.Lab into bl group b by b.Lab into bl
select bl) select bl)
where bl.Count() > 24 where bl.Count() > 49
orderby bl.Count() descending orderby bl.Count() descending
select new Tuple<string, int>(bl.Key, bl.Count()); select new Tuple<string, int>(bl.Key, bl.Count());

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace BuildFeed.Models.ViewModel.Front
{
public class FrontBuildGroup
{
public BuildGroup Key { get; set; }
public DateTime? LastBuild { get; set; }
public int BuildCount { get; set; }
}
}

View File

@ -1,18 +1,18 @@
@model IEnumerable<IGrouping<BuildFeed.Models.BuildGroup, BuildFeed.Models.Build>> @model IEnumerable<BuildFeed.Models.ViewModel.Front.FrontBuildGroup>
@using Humanizer; @using Humanizer;
@{ @{
ViewBag.Title = "BuildFeed"; ViewBag.Title = "BuildFeed";
} }
<div class="row"> <div class="row">
@foreach (var group in Model) @foreach (BuildFeed.Models.ViewModel.Front.FrontBuildGroup group in Model)
{ {
<div class="col-sm-2"> <div class="col-sm-2">
<h3 class="build-group-title"><a href="@Url.Action("viewGroup", new { major = group.Key.Major, minor = group.Key.Minor, number = group.Key.Build, revision = group.Key.Revision })"><span class="icon"><i class="fa fa-plus-square"></i></span> @group.Key.ToString()</a></h3> <h3 class="build-group-title"><a href="@Url.Action("viewGroup", new { major = group.Key.Major, minor = group.Key.Minor, number = group.Key.Build, revision = group.Key.Revision })"><span class="icon"><i class="fa fa-plus-square"></i></span> @group.Key.ToString()</a></h3>
<p> <p>
@if (group.Any(k => k.BuildTime.HasValue)) @if (group.LastBuild.HasValue)
{ {
var maxDate = group.Max(k => k.BuildTime).Value; var maxDate = group.LastBuild.Value;
if (maxDate.AddDays(28) > DateTime.Now) if (maxDate.AddDays(28) > DateTime.Now)
{ {
<span title="@maxDate.ToString("d MMMM yyyy")"><i class="fa fa-calendar fa-fw"></i> @maxDate.Humanize()</span><br /> <span title="@maxDate.ToString("d MMMM yyyy")"><i class="fa fa-calendar fa-fw"></i> @maxDate.Humanize()</span><br />
@ -22,8 +22,45 @@
<span title="@maxDate.Humanize()"><i class="fa fa-calendar fa-fw"></i> @maxDate.ToString("d MMMM yyyy")</span><br /> <span title="@maxDate.Humanize()"><i class="fa fa-calendar fa-fw"></i> @maxDate.ToString("d MMMM yyyy")</span><br />
} }
} }
<i class="fa fa-server fa-fw"></i> @group.Count().ToString() builds <i class="fa fa-server fa-fw"></i> @group.BuildCount builds
</p> </p>
</div> </div>
} }
</div> </div>
@if (ViewBag.PageCount > 1)
{
<div class="text-center">
<ul class="pagination">
@if (ViewBag.PageNumber == 2)
{
<li>@Html.ActionLink(HttpUtility.HtmlDecode("&laquo;"), "index")</li>
}
else if (ViewBag.PageNumber > 2)
{
<li>@Html.ActionLink(HttpUtility.HtmlDecode("&laquo;"), "indexPage", new { page = ViewBag.PageNumber - 1 })</li>
}
else
{
<li class="disabled"><span>&laquo;</span></li>
}
<li @((1 == ViewBag.PageNumber) ? "class=active" : "")>@Html.ActionLink("1", "index")</li>
@for (int i = 2; i <= ViewBag.PageCount; i++)
{
<li @((i == ViewBag.PageNumber) ? "class=active" : "")>@Html.ActionLink(i.ToString(), "indexPage", new { page = i })</li>
}
@if (ViewBag.PageNumber < ViewBag.PageCount)
{
<li>@Html.ActionLink(HttpUtility.HtmlDecode("&raquo;"), "indexPage", new { page = ViewBag.PageNumber + 1 })</li>
}
else
{
<li class="disabled"><span>&raquo;</span></li>
}
</ul>
</div>
}

View File

@ -11,6 +11,17 @@
{ {
<div class="col-sm-3"> <div class="col-sm-3">
<h3 class="build-group-title">@build.Lab</h3> <h3 class="build-group-title">@build.Lab</h3>
<p>
<a href="@Url.Action("viewBuild", new { id = build.Id })" class="btn btn-info btn-xs">Info</a>
@if (User.Identity.IsAuthenticated)
{
<a href="@Url.Action("editBuild", new { id = build.Id })" class="btn btn-primary btn-xs">Edit</a>
if (Roles.IsUserInRole("Administrators"))
{
<a href="@Url.Action("deleteBuild", new { id = build.Id })" class="btn btn-danger btn-xs">Delete</a>
}
}
</p>
<p> <p>
@if (build.BuildTime.HasValue) @if (build.BuildTime.HasValue)
{ {
@ -28,11 +39,6 @@
<span class="label label-danger label-build-status">Unleaked</span> <span class="label label-danger label-build-status">Unleaked</span>
} }
</p> </p>
<p>
<a href="@Url.Action("viewBuild", new { id = build.Id })" class="btn btn-info btn-xs">Info</a>
<a href="@Url.Action("editBuild", new { id = build.Id })" class="btn btn-primary btn-xs">Edit</a>
<a href="@Url.Action("deleteBuild", new { id = build.Id })" class="btn btn-danger btn-xs">Delete</a>
</p>
</div> </div>
} }
</div> </div>

View File

@ -30,8 +30,19 @@
<div class="row"> <div class="row">
@foreach (var build in Model) @foreach (var build in Model)
{ {
<div class="col-sm-3"> <div class="col-sm-2">
<h3 class="build-group-title">@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)</h3> <h3 class="build-group-title">@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)</h3>
<p>
<a href="@Url.Action("viewBuild", new { id = build.Id })" class="btn btn-info btn-xs">Info</a>
@if (User.Identity.IsAuthenticated)
{
<a href="@Url.Action("editBuild", new { id = build.Id })" class="btn btn-primary btn-xs">Edit</a>
if (Roles.IsUserInRole("Administrators"))
{
<a href="@Url.Action("deleteBuild", new { id = build.Id })" class="btn btn-danger btn-xs">Delete</a>
}
}
</p>
<p> <p>
@if (build.BuildTime.HasValue) @if (build.BuildTime.HasValue)
{ {
@ -49,11 +60,6 @@
<span class="label label-danger label-build-status">Unleaked</span> <span class="label label-danger label-build-status">Unleaked</span>
} }
</p> </p>
<p>
<a href="@Url.Action("viewBuild", new { id = build.Id })" class="btn btn-info btn-xs">Info</a>
<a href="@Url.Action("editBuild", new { id = build.Id })" class="btn btn-primary btn-xs">Edit</a>
<a href="@Url.Action("deleteBuild", new { id = build.Id })" class="btn btn-danger btn-xs">Delete</a>
</p>
</div> </div>
} }
</div> </div>

View File

@ -27,6 +27,17 @@
{ {
<div class="col-sm-3"> <div class="col-sm-3">
<h3 class="build-group-title">@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)</h3> <h3 class="build-group-title">@string.Format("{0}.{1}.{2}.{3}", build.MajorVersion, build.MinorVersion, build.Number, build.Revision)</h3>
<p>
<a href="@Url.Action("viewBuild", new { id = build.Id })" class="btn btn-info btn-xs">Info</a>
@if (User.Identity.IsAuthenticated)
{
<a href="@Url.Action("editBuild", new { id = build.Id })" class="btn btn-primary btn-xs">Edit</a>
if (Roles.IsUserInRole("Administrators"))
{
<a href="@Url.Action("deleteBuild", new { id = build.Id })" class="btn btn-danger btn-xs">Delete</a>
}
}
</p>
<p> <p>
@if (!string.IsNullOrEmpty(build.Lab)) @if (!string.IsNullOrEmpty(build.Lab))
{ {
@ -48,11 +59,6 @@
<span class="label label-danger label-build-status">Unleaked</span> <span class="label label-danger label-build-status">Unleaked</span>
} }
</p> </p>
<p>
<a href="@Url.Action("viewBuild", new { id = build.Id })" class="btn btn-info btn-xs">Info</a>
<a href="@Url.Action("editBuild", new { id = build.Id })" class="btn btn-primary btn-xs">Edit</a>
<a href="@Url.Action("deleteBuild", new { id = build.Id })" class="btn btn-danger btn-xs">Delete</a>
</p>
</div> </div>
} }
</div> </div>

View File

@ -13,7 +13,7 @@
<canvas id="stats-compiled" width="960" height="320"></canvas> <canvas id="stats-compiled" width="960" height="320"></canvas>
<h4>Recorded builds in each lab</h4> <h4>Recorded builds in each lab</h4>
<p>Only labs with 25 or more recorded builds are included.</p> <p>Only labs with 50 or more recorded builds are included.</p>
<canvas id="stats-labs" width="960" height="320"></canvas> <canvas id="stats-labs" width="960" height="320"></canvas>
@section scripts @section scripts