feat: add visibility to tutorial folders and articles

This commit is contained in:
Oliver Booth 2024-02-23 17:50:40 +00:00
parent 577f3b0148
commit 9074cf5210
Signed by: oliverbooth
GPG Key ID: E60B570D1B7557B5
7 changed files with 45 additions and 9 deletions

View File

@ -5,6 +5,11 @@ namespace OliverBooth.Data;
/// </summary>
public enum Visibility
{
/// <summary>
/// Used for filtering results. Represents all visibilities.
/// </summary>
None = -1,
/// <summary>
/// The post is private and only visible to the author, or those with the password.
/// </summary>

View File

@ -64,4 +64,10 @@ public interface ITutorialArticle
/// </summary>
/// <value>The update timestamp, or <see langword="null" /> if this article has not been updated.</value>
DateTimeOffset? Updated { get; }
/// <summary>
/// Gets the visibility of this article.
/// </summary>
/// <value>The visibility of the article.</value>
Visibility Visibility { get; }
}

View File

@ -34,4 +34,10 @@ public interface ITutorialFolder
/// </summary>
/// <value>The title.</value>
string Title { get; }
}
/// <summary>
/// Gets the visibility of this article.
/// </summary>
/// <value>The visibility of the article.</value>
Visibility Visibility { get; }
}

View File

@ -35,6 +35,9 @@ internal sealed class TutorialArticle : IEquatable<TutorialArticle>, ITutorialAr
/// <inheritdoc />
public DateTimeOffset? Updated { get; private set; }
/// <inheritdoc />
public Visibility Visibility { get; private set; }
/// <summary>
/// Returns a value indicating whether two instances of <see cref="TutorialArticle" /> are equal.
/// </summary>

View File

@ -20,6 +20,9 @@ internal sealed class TutorialFolder : IEquatable<TutorialFolder>, ITutorialFold
/// <inheritdoc />
public string Title { get; private set; } = string.Empty;
/// <inheritdoc />
public Visibility Visibility { get; private set; }
/// <summary>
/// Returns a value indicating whether two instances of <see cref="TutorialFolder" /> are equal.
/// </summary>
@ -80,4 +83,4 @@ internal sealed class TutorialFolder : IEquatable<TutorialFolder>, ITutorialFold
// ReSharper disable once NonReadonlyMemberInGetHashCode
return Id;
}
}
}

View File

@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using OliverBooth.Data;
using OliverBooth.Data.Web;
namespace OliverBooth.Services;
@ -12,14 +13,17 @@ public interface ITutorialService
/// Gets the articles within a tutorial folder.
/// </summary>
/// <param name="folder">The folder whose articles to retrieve.</param>
/// <param name="visibility">The visibility to filter by. -1 does not filter.</param>
/// <returns>A read-only view of the articles in the folder.</returns>
IReadOnlyCollection<ITutorialArticle> GetArticles(ITutorialFolder folder);
IReadOnlyCollection<ITutorialArticle> GetArticles(ITutorialFolder folder, Visibility visibility = Visibility.None);
/// <summary>
/// Gets the tutorial folders within a specified folder.
/// </summary>
/// <param name="parent">The parent folder.</param>
/// <param name="visibility">The visibility to filter by. -1 does not filter.</param>
/// <returns>A read-only view of the subfolders in the folder.</returns>
IReadOnlyCollection<ITutorialFolder> GetFolders(ITutorialFolder? parent = null);
IReadOnlyCollection<ITutorialFolder> GetFolders(ITutorialFolder? parent = null, Visibility visibility = Visibility.None);
/// <summary>
/// Gets a folder by its ID.

View File

@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
using Cysharp.Text;
using Markdig;
using Microsoft.EntityFrameworkCore;
using OliverBooth.Data;
using OliverBooth.Data.Web;
namespace OliverBooth.Services;
@ -23,20 +24,28 @@ internal sealed class TutorialService : ITutorialService
}
/// <inheritdoc />
public IReadOnlyCollection<ITutorialArticle> GetArticles(ITutorialFolder folder)
public IReadOnlyCollection<ITutorialArticle> GetArticles(ITutorialFolder folder,
Visibility visibility = Visibility.None)
{
if (folder is null) throw new ArgumentNullException(nameof(folder));
using WebContext context = _dbContextFactory.CreateDbContext();
return context.TutorialArticles.Where(a => a.Folder == folder.Id).ToArray();
IQueryable<TutorialArticle> articles = context.TutorialArticles.Where(a => a.Folder == folder.Id);
if (visibility != Visibility.None) articles = articles.Where(a => a.Visibility == visibility);
return articles.ToArray();
}
/// <inheritdoc />
public IReadOnlyCollection<ITutorialFolder> GetFolders(ITutorialFolder? parent = null)
public IReadOnlyCollection<ITutorialFolder> GetFolders(ITutorialFolder? parent = null,
Visibility visibility = Visibility.None)
{
using WebContext context = _dbContextFactory.CreateDbContext();
if (parent is null) return context.TutorialFolders.Where(f => f.Parent == null).ToArray();
return context.TutorialFolders.Where(a => a.Parent == parent.Id).ToArray();
IQueryable<TutorialFolder> folders = context.TutorialFolders;
folders = parent is null ? folders.Where(f => f.Parent == null) : folders.Where(f => f.Parent == parent.Id);
if (visibility != Visibility.None) folders = folders.Where(a => a.Visibility == visibility);
return folders.ToArray();
}
/// <inheritdoc />