Skip to content

Commit

Permalink
Render page Content as Resource
Browse files Browse the repository at this point in the history
  • Loading branch information
killij committed Nov 8, 2023
1 parent c979df0 commit 31a6fb1
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 21 deletions.
2 changes: 2 additions & 0 deletions Childrens-Social-Care-CPD/Contentful/Models/Content.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class Content : IContent
public List<IContent> Items { get; set; }
public RelatedContent RelatedContent { get; set; }

public List<ContentLink> Navigation { get; set; }

[JsonProperty("$metadata")]
public ContentfulMetadata Metadata { get; set; }
public SystemProperties Sys { get; set; }
Expand Down
54 changes: 51 additions & 3 deletions Childrens-Social-Care-CPD/Controllers/ResourcesController.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Childrens_Social_Care_CPD.Configuration;
using Childrens_Social_Care_CPD.Contentful.Models;
using Childrens_Social_Care_CPD.Core.Resources;
using Childrens_Social_Care_CPD.DataAccess;
using Childrens_Social_Care_CPD.Models;
using Microsoft.AspNetCore.Mvc;
using Childrens_Social_Care_CPD.Extensions;
using System.Reflection;

namespace Childrens_Social_Care_CPD.Controllers;

Expand All @@ -18,7 +20,7 @@ public class ResourcesQuery
public int Page { get; set; } = 1;
public ResourceSortOrder SortOrder { get; set; }

public ResourcesQuery()
public ResourcesQuery()
{
Tags = Array.Empty<string>();
}
Expand All @@ -28,12 +30,14 @@ public class ResourcesController : Controller
{
private readonly IFeaturesConfig _featuresConfig;
private readonly IResourcesSearchStrategy _strategy;
private readonly IResourcesRepository _resourcesRepository;

public ResourcesController(IFeaturesConfig featuresConfig, IResourcesSearchStrategy strategy)
public ResourcesController(IFeaturesConfig featuresConfig, IResourcesSearchStrategy strategy, IResourcesRepository resourcesRepository)
{
ArgumentNullException.ThrowIfNull(strategy);
_featuresConfig = featuresConfig;
_strategy = strategy;
_resourcesRepository = resourcesRepository;
}

[Route("resources-learning")]
Expand All @@ -51,4 +55,48 @@ public async Task<IActionResult> Search([FromQuery] ResourcesQuery query, bool p
var viewModel = await _strategy.SearchAsync(query, cancellationToken);
return View(viewModel);
}

[Route("resources-learning/{*pagename:regex(^[[0-9a-z]](\\/?[[0-9a-z\\-]])*\\/?$)}")]
public async Task<IActionResult> Index(string pageName = "home", bool preferenceSet = false, CancellationToken cancellationToken = default)
{
if (!_featuresConfig.IsEnabled(Features.ResourcesAndLearning))
{
return NotFound();
}

pageName = $"resources-learning/{pageName?.TrimEnd('/')}";
(var content, var tags) = await _resourcesRepository.GetByIdAsync(pageName, cancellationToken: cancellationToken);
if (content == null)
{
return NotFound();
}

var properties = new Dictionary<string, string>(tags.ContentCollection.Items.First().ContentfulMetaData.Tags.Where(x => x.Name.StartsWith("Resource:")).Select(x =>
{
var property = x.Name[9..];
var tokens = property.Split('=');
return tokens.Length > 1
? KeyValuePair.Create(tokens[0].Trim(' '), tokens[1].Trim(' '))
: KeyValuePair.Create(property, string.Empty);
}))
{
{ "Published", content.Sys.CreatedAt?.ToString("dd MMMM yyyy") },
{ "Last updated", content.Sys.CreatedAt?.ToString("dd MMMM yyyy") }
};

var contextModel = new ContextModel(
Id: content.Id,
Title: content.Title,
PageName: pageName,
Category: content.Category,
UseContainers: content.SideMenu == null,
PreferenceSet: preferenceSet,
BackLink: content.BackLink);

ViewData["ContextModel"] = contextModel;
ViewData["StateModel"] = new StateModel();
ViewData["Properties"] = properties;

return View("Resource", content);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Childrens_Social_Care_CPD.Controllers;
using Childrens_Social_Care_CPD.DataAccess;
using Childrens_Social_Care_CPD.Extensions;
using Childrens_Social_Care_CPD.GraphQL.Queries;
using Childrens_Social_Care_CPD.Models;

Expand Down Expand Up @@ -33,7 +32,7 @@ private static IEnumerable<string> SanitiseTags(IEnumerable<string> tags, HashSe

private static Tuple<int, int, int> CalculatePageStats(SearchResourcesByTags.ResponseType searchResults, int page)
{
var totalResults = searchResults?.ResourceCollection?.Total ?? 0;
var totalResults = searchResults?.ContentCollection?.Total ?? 0;
var totalPages = (int)Math.Ceiling((decimal)totalResults / PAGE_SIZE);

return Tuple.Create(totalResults, totalPages, Math.Min(page, totalPages));
Expand Down Expand Up @@ -75,7 +74,7 @@ public async Task<ResourcesListViewModel> SearchAsync(ResourcesQuery query, Canc

return new ResourcesListViewModel(
pageContent,
searchResults?.ResourceCollection,
searchResults?.ContentCollection,
tagInfos,
query.Tags,
(int)query.SortOrder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private IEnumerable<string> GetQueryTags(int[] tags)

private static Tuple<int, int, int> CalculatePageStats(SearchResourcesByTags.ResponseType searchResults, int page)
{
var totalResults = searchResults?.ResourceCollection?.Total ?? 0;
var totalResults = searchResults?.ContentCollection?.Total ?? 0;
var totalPages = (int)Math.Ceiling((decimal)totalResults / PAGE_SIZE);

return Tuple.Create(totalResults, totalPages, Math.Min(page, totalPages));
Expand Down Expand Up @@ -84,7 +84,7 @@ public async Task<ResourcesListViewModel> SearchAsync(ResourcesQuery query, Canc

return new ResourcesListViewModel(
pageContent,
searchResults?.ResourceCollection,
searchResults?.ContentCollection,
_tagInfos,
queryTags.Select(x => x.ToString()),
(int)query.SortOrder,
Expand Down
21 changes: 20 additions & 1 deletion Childrens-Social-Care-CPD/DataAccess/ResourcesRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Childrens_Social_Care_CPD.GraphQL.Queries;
using Contentful.Core.Search;
using GraphQL.Client.Abstractions.Websocket;
using System.Diagnostics;

namespace Childrens_Social_Care_CPD.DataAccess;

Expand All @@ -15,6 +14,7 @@ public interface IResourcesRepository
Task<Content> FetchRootPageAsync(CancellationToken cancellationToken = default);
Task<SearchResourcesByTags.ResponseType> FindByTagsAsync(IEnumerable<string> tags, int skip, int take, ResourceSortOrder resourceSortOrder, CancellationToken cancellationToken = default);
Task<IEnumerable<TagInfo>> GetSearchTagsAsync();
Task<Tuple<Content, GetContentTags.ResponseType>> GetByIdAsync(string id, int depth = 10, CancellationToken cancellationToken = default);
}

public class ResourcesRepository : IResourcesRepository
Expand Down Expand Up @@ -52,6 +52,25 @@ public Task<Content> FetchRootPageAsync(CancellationToken cancellationToken = de
.ContinueWith(x => x.Result.Data);
}

public async Task<Tuple<Content, GetContentTags.ResponseType>> GetByIdAsync(string id, int depth = 10, CancellationToken cancellationToken = default)
{
var queryBuilder = QueryBuilder<Content>.New
.ContentTypeIs("content")
.Include(depth)
.FieldEquals("fields.id", id);

var tagsTask = _gqlClient
.SendQueryAsync<GetContentTags.ResponseType>(GetContentTags.Query(id, _isPreview), cancellationToken)
.ContinueWith(x => x.Result.Data);

var contentTask = _cpdClient
.GetEntries(queryBuilder, cancellationToken)
.ContinueWith(x => x.Result.FirstOrDefault());

await Task.WhenAll(contentTask, tagsTask);
return Tuple.Create(contentTask.Result, tagsTask.Result);
}

public async Task<IEnumerable<TagInfo>> GetSearchTagsAsync()
{
var allTags = await _cpdClient.GetTags();
Expand Down
78 changes: 78 additions & 0 deletions Childrens-Social-Care-CPD/GraphQL/Queries/GetContentTags.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using GraphQL;
using System.Text.Json.Serialization;

namespace Childrens_Social_Care_CPD.GraphQL.Queries;

public class GetContentTags
{
public static GraphQLRequest Query(string id, bool preview = false)
{
return new GraphQLRequest
{
Query = @"
query GetContentTags($id: String!, $preview: Boolean) {
contentCollection(where: {
id : $id,
}, preview: $preview) {
total
items {
id
sys {
publishedAt
firstPublishedAt
}
contentfulMetadata {
tags {
id
name
}
}
}
}
}",
OperationName = "GetContentTags",
Variables = new
{
id,
preview,
}
};
}

public class ResponseType
{
[JsonPropertyName("contentCollection")]
public ContentCollection ContentCollection { get; set; }
}

public class ContentCollection
{
[JsonPropertyName("items")]
public ICollection<ContentItem> Items { get; set; }
public int Total { get; set; }
}

public class ContentItem
{
public string Id { get; set; }
public PublishedInfo Sys { get; set; }
public MetaData ContentfulMetaData { get; set; }
}

public class PublishedInfo
{
public DateTime? PublishedAt { get; set; }
public DateTime? FirstPublishedAt { get; set; }
}

public class MetaData
{
public List<Tag> Tags { get; set; }
}

public class Tag
{
public string Id { get; set; }
public string Name { get; set; }
}
}
4 changes: 1 addition & 3 deletions Childrens-Social-Care-CPD/Models/ResourcesListViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Childrens_Social_Care_CPD.Contentful.Models;
using Childrens_Social_Care_CPD.Controllers;
using Childrens_Social_Care_CPD.Core.Resources;
using Childrens_Social_Care_CPD.GraphQL.Queries;

Expand All @@ -12,10 +11,9 @@ public static class ResourceSort
public const string MostViewed = "Most viewed";
}


public record ResourcesListViewModel(
Content Content,
SearchResourcesByTags.ResourceCollection Results,
SearchResourcesByTags.ContentCollection Results,
IEnumerable<TagInfo> TagInfos,
IEnumerable<string> SelectedTags,
int SortOrder = 0,
Expand Down
6 changes: 6 additions & 0 deletions Childrens-Social-Care-CPD/TagHelpers/CpdResourceNav.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public class CpdResourceNav : TagHelper

public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (Navigation == null || Navigation.Count == 0)
{
output.SuppressOutput();
return;
}

output.TagName = "nav";
output.TagMode = TagMode.StartTagAndEndTag;
output.AddClass("gem-c-contents-list", HtmlEncoder.Default);
Expand Down
Loading

0 comments on commit 31a6fb1

Please sign in to comment.