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

Feature/side nav (#128) #129

Closed
wants to merge 1 commit into from
Closed
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,41 @@
:root {
--govuk-link-color: #1d70b8;
--govuk-black: #0b0c0c;
}

.dfe-vertical-nav__section-item {
list-style-type: none;
font-size: 1rem;
}

.dfe-vertical-nav__link {
display: block;
padding: 7px 30px 8px 10px;
border-left: 4px solid #b1b4b6;
text-decoration: none;
}

.dfe-vertical-nav__link--selected {
border-left: 4px solid var(--govuk-link-color);
background-color: #f3f2f1;
font-weight: bold;
}

.dfe-vertical-nav__link,
.dfe-vertical-nav__link--selected {
color: var(--govuk-link-color);

&:active, &:hover {
background-color: #fd0;
color: var(--govuk-black);
border-left: 4px solid var(--govuk-black);
font-weight: normal;
}
}

.dfe-vertical-nav__theme {
border-top: 1px solid var(--govuk-link-color);
padding-top: 5px;
margin-top: 10px;
margin-left: 0;
}
11 changes: 7 additions & 4 deletions src/Dfe.ContentSupport.Web/Controllers/ContentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Dfe.ContentSupport.Web.Controllers;

[Route("/content")]
[AllowAnonymous]
public class ContentController(IContentService contentService)
public class ContentController(IContentService contentService, ILayoutService layoutService)
: Controller
{
public async Task<IActionResult> Home()
Expand All @@ -28,14 +28,17 @@ public async Task<IActionResult> Home()
return View(defaultModel);
}

[HttpGet("{slug}")]
public async Task<IActionResult> Index(string slug, bool isPreview = false)
[HttpGet("{slug}/{page?}")]
public async Task<IActionResult> Index(string slug, string page = "", bool isPreview = false)
{
if (!ModelState.IsValid) return RedirectToAction("error");
if (string.IsNullOrEmpty(slug)) return RedirectToAction("error");

var resp = await contentService.GetContent(slug, isPreview);
if (resp is null) return RedirectToAction("error");

resp = layoutService.GenerateLayout(resp, Request, page);

return View("CsIndex", resp);
}

Expand All @@ -48,6 +51,6 @@ public IActionResult Privacy()
public IActionResult Error()
{
return View(new ErrorViewModel
{ RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
{ RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static void InitCsDependencyInjection(this WebApplicationBuilder app)
app.Services.AddTransient<IModelMapper, ModelMapper>();
app.Services.AddTransient<IContentfulService, ContentfulService>();
app.Services.AddTransient<IContentService, ContentService>();
app.Services.AddTransient<ILayoutService, LayoutService>();

app.Services.Configure<CookiePolicyOptions>(options =>
{
Expand Down
4 changes: 4 additions & 0 deletions src/Dfe.ContentSupport.Web/Models/ContentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ namespace Dfe.ContentSupport.Web.Models;
public class ContentBase : ContentType
{
public string InternalName { get; set; } = null!;

public string? Title { get; set; } = null;

public string? Subtitle { get; set; } = null;
}
2 changes: 2 additions & 0 deletions src/Dfe.ContentSupport.Web/Models/Mapped/CsContentItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ namespace Dfe.ContentSupport.Web.Models.Mapped;
public class CsContentItem
{
public string InternalName { get; set; } = null!;
public string? Title { get; set; } = null;
public string? Subtitle { get; set; } = null;
}
3 changes: 3 additions & 0 deletions src/Dfe.ContentSupport.Web/Models/Mapped/CsPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ public class CsPage
public string Slug { get; set; } = null!;
public bool IsSitemap { get; set; }
public bool HasCitation { get; set; }
public bool ShowVerticalNavigation { get; set; }
public bool HasBackToTop { get; set; }
public List<CsContentItem> Content { get; set; } = null!;
public DateTime? CreatedAt { get; init; }
public DateTime? UpdatedAt { get; init; }
public List<PageLink>? MenuItems { get; set; }

}
10 changes: 10 additions & 0 deletions src/Dfe.ContentSupport.Web/Models/Mapped/PageLink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Dfe.ContentSupport.Web.Models.Mapped
{
public class PageLink
{
public string? Title { get; set; } = null;
public string? Subtitle { get; set; } = null;
public required string Url { get; set; }
public required bool IsActive { get; set; }
}
}
2 changes: 1 addition & 1 deletion src/Dfe.ContentSupport.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static void Main(string[] args)

app.MapControllerRoute(
name: "slug",
pattern: "{slug}",
pattern: "{slug}/{page?}",
defaults: new { controller = "Content", action = "Index" });


Expand Down
10 changes: 10 additions & 0 deletions src/Dfe.ContentSupport.Web/Services/ILayoutService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Dfe.ContentSupport.Web.Models.Mapped;

namespace Dfe.ContentSupport.Web.Services
{
public interface ILayoutService
{
CsPage GenerateLayout(CsPage page, HttpRequest request, string pageName);

}
}
85 changes: 85 additions & 0 deletions src/Dfe.ContentSupport.Web/Services/LayoutService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Dfe.ContentSupport.Web.Models;
using Dfe.ContentSupport.Web.Models.Mapped;


namespace Dfe.ContentSupport.Web.Services
{
public class LayoutService : ILayoutService
{
public CsPage GenerateLayout(CsPage page, HttpRequest request, string pageName)
{
if (!page.ShowVerticalNavigation) return page;

return new()
{
Heading = GetHeading(page, pageName),
MenuItems = GenerateVerticalNavigation(page, request, pageName),
Content = GetVisiblePageList(page, pageName),
UpdatedAt = page.UpdatedAt,
CreatedAt = page.CreatedAt,
HasCitation = page.HasCitation,
HasBackToTop = page.HasBackToTop,
IsSitemap = page.IsSitemap,
ShowVerticalNavigation = page.ShowVerticalNavigation,
Slug = page.Slug,
};
}


public Heading GetHeading(CsPage page, string pageName)
{
var selectedPage = page.Content.Find(o => o.InternalName == pageName);

if (selectedPage != null)
return new()
{
Title = selectedPage.Title ?? "",
Subtitle = selectedPage.Subtitle ?? ""
};


return new()
{
Title = page.Content[0]?.Title ?? "",
Subtitle = page.Content[0]?.Subtitle ?? ""
};
}


public List<PageLink> GenerateVerticalNavigation(CsPage page, HttpRequest request, string pageName)
{
var baseUrl = GetNavigationUrl(request);

var menuItems = page.Content.Select(o => new PageLink()
{
Title = o.Title ?? "",
Subtitle = o.Subtitle ?? "",
Url = $"{baseUrl}/{o.InternalName}",
IsActive = pageName == o.InternalName
}).ToList();

if (string.IsNullOrEmpty(pageName) && menuItems.Count > 0)
menuItems[0].IsActive = true;

return menuItems;
}


public List<CsContentItem> GetVisiblePageList(CsPage page, string pageName)
{
if (!string.IsNullOrEmpty(pageName))
return page.Content.Where(o => o.InternalName == pageName).ToList();


return page.Content.GetRange(0, 1);
}


public string GetNavigationUrl(HttpRequest request)
{
var splitUrl = request.Path.ToString().Split("/");
return string.Join("/", splitUrl.Take(3));
}

}
}
17 changes: 10 additions & 7 deletions src/Dfe.ContentSupport.Web/Services/ModelMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public CsPage MapToCsPage(ContentSupportPage incoming)
HasCitation = incoming.HasCitation,
HasBackToTop = incoming.HasBackToTop,
Content = MapEntriesToContent(incoming.Content),
ShowVerticalNavigation = incoming.ShowVerticalNavigation,
CreatedAt = incoming.Sys.CreatedAt,
UpdatedAt = incoming.Sys.UpdatedAt
};
Expand All @@ -40,18 +41,20 @@ private List<CsContentItem> MapEntriesToContent(List<Entry> entries)
public CsContentItem ConvertEntryToContentItem(Entry entry)
{
CsContentItem item = entry.RichText is not null
? MapRichTextContent(entry.RichText)!
: new CsContentItem { InternalName = entry.InternalName };
? MapRichTextContent(entry.RichText, entry)!
: new CsContentItem { InternalName = entry.InternalName, Title = entry.Title, Subtitle = entry.Subtitle };
return item;
}

public RichTextContentItem? MapRichTextContent(ContentItemBase? richText)
public RichTextContentItem? MapRichTextContent(ContentItemBase? richText, Entry entry)
{
if (richText is null) return null;
RichTextContentItem item =
new RichTextContentItem
{
InternalName = richText.InternalName,
InternalName = entry.InternalName,
Title = entry.Title,
Subtitle = entry.Subtitle,
NodeType = ConvertToRichTextNodeType(richText.NodeType),
Content = MapRichTextNodes(richText.Content),
};
Expand All @@ -61,7 +64,7 @@ public CsContentItem ConvertEntryToContentItem(Entry entry)
public List<RichTextContentItem> MapRichTextNodes(List<ContentItem> nodes)
{
return nodes.Select(node => MapContent(node) ?? new RichTextContentItem
{ NodeType = RichTextNodeType.Unknown, InternalName = node.InternalName }).ToList();
{ NodeType = RichTextNodeType.Unknown, InternalName = node.InternalName }).ToList();
}

public RichTextContentItem? MapContent(ContentItem contentItem)
Expand Down Expand Up @@ -101,7 +104,7 @@ public List<RichTextContentItem> MapRichTextNodes(List<ContentItem> nodes)
item = new EmbeddedEntry
{
JumpIdentifier = target.JumpIdentifier,
RichText = MapRichTextContent(target.RichText),
RichText = MapRichTextContent(target.RichText, target),
CustomComponent = GenerateCustomComponent(target)
};
break;
Expand Down Expand Up @@ -154,7 +157,7 @@ private CustomAccordion GenerateCustomAccordion(Target target)
return new CustomAccordion
{
InternalName = target.InternalName,
Body = MapRichTextContent(target.RichText),
Body = MapRichTextContent(target.RichText, target),
SummaryLine = target.SummaryLine,
Title = target.Title,
Accordions = target.Content.Select(GenerateCustomAccordion).ToList()
Expand Down
5 changes: 2 additions & 3 deletions src/Dfe.ContentSupport.Web/ViewModels/ContentSupportPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ namespace Dfe.ContentSupport.Web.ViewModels;
public class ContentSupportPage : ContentBase
{
public string Slug { get; init; } = null!;

public List<dynamic> BeforeTitleContent { get; init; } = [];

public Heading Heading { get; init; } = null!;
public List<Entry> Content { get; init; } = [];

public bool DisplayBackButton { get; init; }
public bool IsSitemap { get; init; }
public bool HasCitation { get; init; }
public bool HasBackToTop { get; init; }
public bool ShowVerticalNavigation { get; init; }

}
21 changes: 21 additions & 0 deletions src/Dfe.ContentSupport.Web/Views/Content/CsIndex.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,34 @@
}

<div class="govuk-grid-row">

@if (Model.MenuItems is not null)
{
<div class="govuk-grid-column-one-quarter sticky">
<nav class="dfe-vertical-nav">
<div class="dfe-vertical-nav__section">
<ul class="dfe-vertical-nav__section">
@foreach (var menuItem in Model.MenuItems)
{
<li class="dfe-vertical-nav__section-item">
<a class="dfe-vertical-nav__link @(menuItem.IsActive ? "dfe-vertical-nav__section-item--current" : "")" href="@menuItem.Url">@(string.IsNullOrEmpty(menuItem.Subtitle) ? "" : $"{menuItem.Subtitle} : ") @menuItem.Title </a>
</li>
}
</ul>
</div>
</nav>
</div>
}

<div class="govuk-grid-column-three-quarters">

@foreach (var content in Model.Content)
{
<partial name="_Content" model="@content" />
}
</div>

<div class="govuk-grid-column-full">
@if (Model.HasCitation)
{
<partial name="_Citation" model="Model" />
Expand Down
Loading
Loading