Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added highlightning to admin menu #2320

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using AllReady.TagHelpers;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Xunit;

namespace AllReady.UnitTest.TagHelpers
{
public class ActiveRouteTagHelperShould
{
private const string controllerName = "Home";
private const string actionName = "List";
private Dictionary<string, string> routeValue = new Dictionary<string, string> { { "Id", "2" } };
private const string page = "/index";

private const string notMatchingControllerName = "HomeX";
private const string notMatchingActionName = "Index";
private Dictionary<string, string> notMathingRouteValue = new Dictionary<string, string> { { "Id", "3" } };
private const string notMatchingPage = "/index2";

private Func<bool, HtmlEncoder, Task<TagHelperContent>> GetEmptyChildContent()
{
TagHelperContent content = new DefaultTagHelperContent();
return (b, encoder) => Task.FromResult(content);
}

private TagHelperContext GetContext()
{
return new TagHelperContext(new TagHelperAttributeList(), new Dictionary<object, object>(), Guid.NewGuid().ToString());
}

private TagHelperOutput GetOutput()
{
return new TagHelperOutput("time", new TagHelperAttributeList(), GetEmptyChildContent());
}

private ViewContext GetViewContextMVC()
{
var viewContext = new ViewContext();
viewContext.RouteData = new Microsoft.AspNetCore.Routing.RouteData();
viewContext.RouteData.Values.Add("Controller", controllerName);
viewContext.RouteData.Values.Add("Action", actionName);
viewContext.RouteData.Values.Add("Id", "2");
return viewContext;
}

private ViewContext GetViewContextPage()
{
var viewContext = new ViewContext();
viewContext.RouteData = new Microsoft.AspNetCore.Routing.RouteData();
viewContext.RouteData.Values.Add("page", page);
return viewContext;
}

[Fact]
public void NotHaveClassAttributeIfNoClassPassedInAndIfNoParametersPassedIn()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextMVC()
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(0, output.Attributes.Count);
}

[Fact]
public void HaveActiveClassAttributeWhenControllerMatch()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextMVC(),
Controller = controllerName
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(1, output.Attributes.Count);
Assert.Equal("class", output.Attributes[0].Name);
Assert.Equal("active", output.Attributes[0].Value);
}

[Fact]
public void NotHaveClassAttributeWhenControllerNotMatching()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextMVC(),
Controller = notMatchingControllerName
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(0, output.Attributes.Count);
}

[Fact]
public void HaveActiveClassAttributeWhenActionMatch()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextMVC(),
Controller = controllerName,
Action = actionName
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(1, output.Attributes.Count);
Assert.Equal("class", output.Attributes[0].Name);
Assert.Equal("active", output.Attributes[0].Value);
}

[Fact]
public void NotHaveClassAttributeWhenActionNotMatching()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextMVC(),
Controller = controllerName,
Action = notMatchingActionName
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(0, output.Attributes.Count);
}

[Fact]
public void HaveActiveClassAttributeWhenRouteDataMatch()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextMVC(),
Controller = controllerName,
Action = actionName,
RouteValues = routeValue
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(1, output.Attributes.Count);
Assert.Equal("class", output.Attributes[0].Name);
Assert.Equal("active", output.Attributes[0].Value);
}

[Fact]
public void NotHaveClassAttributeWhenRouteDataNotMatching()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextMVC(),
Controller = controllerName,
Action = actionName,
RouteValues = notMathingRouteValue
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(0, output.Attributes.Count);
}

[Fact]
public void HaveActiveClassAttributePageMatch()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextPage(),
Page = page
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(1, output.Attributes.Count);
Assert.Equal("class", output.Attributes[0].Name);
Assert.Equal("active", output.Attributes[0].Value);
}

[Fact]
public void NotHaveClassAttributeWhenPageNotMatching()
{
ActiveRouteTagHelper tagHelper = new ActiveRouteTagHelper
{
ViewContext = GetViewContextPage(),
Page = notMatchingPage
};
var output = GetOutput();
tagHelper.Process(GetContext(), output);
Assert.Equal(0, output.Attributes.Count);
}
}
}
143 changes: 143 additions & 0 deletions AllReadyApp/Web-App/AllReady/TagHelpers/ActiveRouteTagHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AllReady.TagHelpers
{
[HtmlTargetElement(Attributes = "is-active-route")]
public class ActiveRouteTagHelper : TagHelper
{
private IDictionary<string, string> _routeValues;

/// <summary>
/// Name of the action method
/// </summary>
[HtmlAttributeName("asp-action")]
public string Action { get; set; }

/// <summary>
/// Name of the controller
/// </summary>
[HtmlAttributeName("asp-controller")]
public string Controller { get; set; }

/// <summary>
/// Name of the razor page (e.g. /index)
/// </summary>
[HtmlAttributeName("asp-page")]
public string Page { get; set; }

/// <summary>
/// Additional route parameters
/// </summary>
[HtmlAttributeName("asp-all-route-data", DictionaryAttributePrefix = "asp-route-")]
public IDictionary<string, string> RouteValues
{
get
{
if (_routeValues == null)
_routeValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
return _routeValues;
}
set
{
_routeValues = value;
}
}

/// <summary>
/// The ViewContext
/// </summary>
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }

public override void Process(TagHelperContext context, TagHelperOutput output)
{
base.Process(context, output);

if (ShouldBeActive())
{
MakeActive(output);
}

output.Attributes.RemoveAll("is-active-route");
}

private bool ShouldBeActive()
{
if (ViewContext.RouteData.Values.ContainsKey("Controller"))
{
return ShouldBeActieMvc();
}
else if (ViewContext.RouteData.Values.ContainsKey("page"))
{
return ShouldBeActiveRazorPage();
}
return true;
}

private bool ShouldBeActieMvc()
{
if (string.IsNullOrWhiteSpace(Controller) &&
string.IsNullOrWhiteSpace(Action) &&
!RouteValues.Any(r => !ViewContext.RouteData.Values.ContainsKey(r.Key)))
{
return false;
}

string currentController = ViewContext.RouteData.Values["Controller"].ToString();
string currentAction = ViewContext.RouteData.Values["Action"].ToString();

if (!string.IsNullOrWhiteSpace(Controller) && Controller.ToLower() != currentController.ToLower())
{
return false;
}

if (!string.IsNullOrWhiteSpace(Action) && Action.ToLower() != currentAction.ToLower())
{
return false;
}

foreach (var routeValue in RouteValues)
{
if (!ViewContext.RouteData.Values.ContainsKey(routeValue.Key) ||
ViewContext.RouteData.Values[routeValue.Key].ToString() != routeValue.Value)
{
return false;
}
}
return true;
}

private bool ShouldBeActiveRazorPage()
{
string currentPage = ViewContext.RouteData.Values["Page"].ToString();

if (string.IsNullOrWhiteSpace(Page) || Page.ToLower() != currentPage.ToLower())
{
return false;
}
return true;
}

private void MakeActive(TagHelperOutput output)
{
var classAttr = output.Attributes.FirstOrDefault(a => a.Name == "class");
if (classAttr == null)
{
classAttr = new TagHelperAttribute("class", "active");
output.Attributes.Add(classAttr);
}
else if (classAttr.Value == null || classAttr.Value.ToString().IndexOf("active") < 0)
{
output.Attributes.SetAttribute("class", classAttr.Value == null
? "active"
: classAttr.Value.ToString() + " active");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
<ul class="dropdown-menu">
@if (User.IsUserType(UserType.SiteAdmin))
{
<li><a asp-area="@AreaNames.Admin" asp-controller="Organization" asp-action="Index">Organizations</a></li>
<li is-active-route asp-controller="Organization" asp-action="Index"><a asp-area="@AreaNames.Admin" asp-controller="Organization" asp-action="Index">Organizations</a></li>
}
<li><a asp-area="@AreaNames.Admin" asp-controller="Campaign" asp-action="Index">Campaigns</a></li>
<li is-active-route asp-controller="Campaign" asp-action="Index"><a asp-area="@AreaNames.Admin" asp-controller="Campaign" asp-action="Index">Campaigns</a></li>
@if (User.IsUserType(UserType.OrgAdmin))
{
<li><a asp-area="@AreaNames.Admin" asp-controller="UnlinkedRequest" asp-action="List">Unlinked Requests</a></li>
<li><a asp-area="Admin" asp-controller="Invite" asp-action="Index">Invites</a></li>
<li is-active-route asp-controller="UnlinkedRequest" asp-action="List"><a asp-area="@AreaNames.Admin" asp-controller="UnlinkedRequest" asp-action="List">Unlinked Requests</a></li>
<li is-active-route asp-controller="Invite" asp-action="Index"><a asp-area="Admin" asp-controller="Invite" asp-action="Index">Invites</a></li>
}
<li><a asp-area="@AreaNames.Admin" asp-controller="Event" asp-action="Lister">Events</a></li>
<li><a asp-area="@AreaNames.Admin" asp-controller="Skill" asp-action="Index">Skills</a></li>
<li is-active-route asp-controller="Event" asp-action="Lister"><a asp-area="@AreaNames.Admin" asp-controller="Event" asp-action="Lister">Events</a></li>
<li is-active-route asp-controller="Skill" asp-action="Index"><a asp-area="@AreaNames.Admin" asp-controller="Skill" asp-action="Index">Skills</a></li>
@if (User.IsUserType(UserType.SiteAdmin))
{
<li><a asp-area="@AreaNames.Admin" asp-controller="Site" asp-action="Index">Site Admin</a></li>
<li is-active-route asp-controller="Site" asp-action="Index"><a asp-area="@AreaNames.Admin" asp-controller="Site" asp-action="Index">Site Admin</a></li>
}
<li><a asp-area="@AreaNames.Admin" asp-controller="Import" asp-action="Index">Import Data</a></li>
<li is-active-route asp-controller="Import" asp-action="Index"><a asp-area="@AreaNames.Admin" asp-controller="Import" asp-action="Index">Import Data</a></li>
</ul>
</li>
}
Loading