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

Adjust web side for new tooling changes (Key -> Keys and OrderOnPage) #674

Merged
merged 20 commits into from
Dec 14, 2024
Merged
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
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
<ToolingPackagesVersion>1.1.1.4415</ToolingPackagesVersion>
<ToolingPackagesVersion>1.1.1.4520</ToolingPackagesVersion>
<AccessToNugetFeed>true</AccessToNugetFeed>
<RestoreSources>
https://api.nuget.org/v3/index.json;
Expand Down
14 changes: 8 additions & 6 deletions EssentialCSharp.Web.Tests/SiteMappingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace EssentialCSharp.Web.Tests;
public class SiteMappingTests
{
static SiteMapping HelloWorldSiteMapping => new(
key: "hello-world",
keys: ["hello-world"],
pagePath:
[
"Chapters",
Expand All @@ -15,14 +15,15 @@ public class SiteMappingTests
],
chapterNumber: 1,
pageNumber: 1,
orderOnPage: 1,
chapterTitle: "Introducing C#",
rawHeading: "Introduction",
anchorId: "hello-world",
indentLevel: 0
);

static SiteMapping CSyntaxFundamentalsSiteMapping => new(
key: "c-syntax-fundamentals",
keys: ["c-syntax-fundamentals"],
pagePath:
[
"Chapters",
Expand All @@ -32,6 +33,7 @@ public class SiteMappingTests
],
chapterNumber: 1,
pageNumber: 2,
orderOnPage: 1,
chapterTitle: "Introducing C#",
rawHeading: "C# Syntax Fundamentals",
anchorId: "c-syntax-fundamentals",
Expand All @@ -52,30 +54,30 @@ public void FindHelloWorldWithAnchorSlugReturnsCorrectSiteMap()
{
SiteMapping? foundSiteMap = GetSiteMap().Find("hello-world#hello-world");
Assert.NotNull(foundSiteMap);
Assert.Equal(HelloWorldSiteMapping, foundSiteMap);
Assert.Equivalent(HelloWorldSiteMapping, foundSiteMap);
}

[Fact]
public void FindCSyntaxFundamentalsWithSpacesReturnsCorrectSiteMap()
{
SiteMapping? foundSiteMap = GetSiteMap().Find("C# Syntax Fundamentals");
Assert.NotNull(foundSiteMap);
Assert.Equal(CSyntaxFundamentalsSiteMapping, foundSiteMap);
Assert.Equivalent(CSyntaxFundamentalsSiteMapping, foundSiteMap);
}

[Fact]
public void FindCSyntaxFundamentalsWithSpacesAndAnchorReturnsCorrectSiteMap()
{
SiteMapping? foundSiteMap = GetSiteMap().Find("C# Syntax Fundamentals#hello-world");
Assert.NotNull(foundSiteMap);
Assert.Equal(CSyntaxFundamentalsSiteMapping, foundSiteMap);
Assert.Equivalent(CSyntaxFundamentalsSiteMapping, foundSiteMap);
}

[Fact]
public void FindCSyntaxFundamentalsSanitizedWithAnchorReturnsCorrectSiteMap()
{
SiteMapping? foundSiteMap = GetSiteMap().Find("c-syntax-fundamentals#hello-world");
Assert.NotNull(foundSiteMap);
Assert.Equal(CSyntaxFundamentalsSiteMapping, foundSiteMap);
Assert.Equivalent(CSyntaxFundamentalsSiteMapping, foundSiteMap);
}
}
2 changes: 1 addition & 1 deletion EssentialCSharp.Web/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private string FlipPage(int currentChapter, int currentPage, bool next)
return "";
}
}
return $"{siteMap.Key}#{siteMap.AnchorId}";
return $"{siteMap.Keys.First()}#{siteMap.AnchorId}";
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static class SiteMappingListExtensions
}
foreach (string? potentialMatch in key.GetPotentialMatches())
{
if (siteMappings.FirstOrDefault(x => x.Key == potentialMatch) is { } siteMap)
if (siteMappings.FirstOrDefault(x => x.Keys.Any(x => x == potentialMatch)) is { } siteMap)
{
return siteMap;
}
Expand Down
1 change: 1 addition & 0 deletions EssentialCSharp.Web/Services/ISiteMappingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public interface ISiteMappingService
{
IList<SiteMapping> SiteMappings { get; }
IEnumerable<SiteMappingDto> GetTocData();
}
12 changes: 12 additions & 0 deletions EssentialCSharp.Web/Services/SiteMappingDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace EssentialCSharp.Web.Services;

// Data transfer object to pass necessary SiteMapping data info
// to frontend for use in table of contents
public class SiteMappingDto
BenjaminMichaelis marked this conversation as resolved.
Show resolved Hide resolved
{
public required int Level { get; set; }
public required string Key { get; set; }
public required string Href { get; set; }
public required string Title { get; set; }
public required IEnumerable<SiteMappingDto> Items { get; set; }
}
38 changes: 38 additions & 0 deletions EssentialCSharp.Web/Services/SiteMappingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,42 @@ public SiteMappingService(IWebHostEnvironment webHostEnvironment)
List<SiteMapping>? siteMappings = System.Text.Json.JsonSerializer.Deserialize<List<SiteMapping>>(File.OpenRead(path)) ?? throw new InvalidOperationException("No table of contents found");
SiteMappings = siteMappings;
}

public IEnumerable<SiteMappingDto> GetTocData()
{
return SiteMappings.GroupBy(x => x.ChapterNumber).OrderBy(x => x.Key).Select(x =>
{
IEnumerable<SiteMapping> orderedGrouping = x.OrderBy(i => i.PageNumber).ThenBy(i => i.OrderOnPage);
SiteMapping firstElement = orderedGrouping.First();
return new SiteMappingDto()
{
Level = 0,
Key = firstElement.Keys.First(),
Href = $"{firstElement.Keys.First()}#{firstElement.AnchorId}",
Title = $"Chapter {x.Key}: {firstElement.ChapterTitle}",
Items = GetItems(orderedGrouping.Skip(1), 1)
};
}
);
}

private static IEnumerable<SiteMappingDto> GetItems(IEnumerable<SiteMapping> chapterItems, int indentLevel)
{
return chapterItems
// Examine all items up until we move up to a level higher than where we're starting,
// which would indicate that we've reached the end of the entries nested under `indentationLevel`
.TakeWhile(i => i.IndentLevel >= indentLevel)
// Of all the multi-level descendants we found, take only those at the current level that we're wanting to render.
.Where(i => i.IndentLevel == indentLevel)
.Select(i => new SiteMappingDto()
{
Level = indentLevel,
Key = i.Keys.First(),
Href = $"{i.Keys.First()}#{i.AnchorId}",
Title = i.RawHeading,
// Any children of this node will be /after/ this node,
// so skip any items that are /before/ the current node.
Items = GetItems(chapterItems.SkipWhile(q => i.Keys.First() != q.Keys.First()).Skip(1), indentLevel + 1)
});
}
}
27 changes: 1 addition & 26 deletions EssentialCSharp.Web/Views/Shared/_Layout.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -266,32 +266,7 @@
@await RenderSectionAsync("Scripts", required: false);
<script>
@{
object GetItems(IEnumerable<SiteMapping> chapterItems, int indentLevel) => chapterItems
// Skip the chapter entry itself
.Skip(1)
// Examine all items up until we move up to a level higher than where we're starting,
// which would indicate that we've reached the end of the entries nested under `indentationLevel`
.TakeWhile(i => i.IndentLevel >= indentLevel)
// Of all the multi-level descendants we found, take only those at the current level that we're wanting to render.
.Where(i => i.IndentLevel == indentLevel)
.Select(i => new
{
Level = indentLevel,
Key = i.Key,
Href = $"{i.Key}#{i.AnchorId}",
Title = i.RawHeading,
// Any children of this node will be /after/ this node,
// so skip any items that are /before/ the current node.
Items = GetItems(chapterItems.SkipWhile(q => i.Key != q.Key), indentLevel + 1)
});
var tocData = _SiteMappings.SiteMappings.GroupBy(x => x.ChapterNumber).OrderBy(x => x.Key).Select(x => new
{
Level = 0,
Key = x.First().Key,
Href = $"{x.First().Key}#{x.First().AnchorId}",
Title = $"Chapter {x.Key}: {x.First().ChapterTitle}",
Items = GetItems(x, 1)
});
var tocData = _SiteMappings.GetTocData();
}

PREVIOUS_PAGE = @Json.Serialize(ViewBag.PreviousPage)
Expand Down
Loading