Add post list and category manipulation

This commit is contained in:
2022-04-23 17:53:40 -04:00
parent e8b903b33b
commit a58cc25bbb
14 changed files with 603 additions and 71 deletions

View File

@@ -307,3 +307,10 @@ module WebLogUser =
url = None
authorizationLevel = User
}
/// Get the user's displayed name
let displayName user =
let name =
seq { match user.preferredName with "" -> user.firstName | n -> n; " "; user.lastName }
|> Seq.reduce (+)
name.Trim ()

View File

@@ -144,6 +144,12 @@ type PostStatus =
/// The post is publicly viewable
| Published
/// Functions to support post statuses
module PostStatus =
/// Convert a post status to a string
let toString = function Draft -> "Draft" | Published -> "Published"
/// An identifier for a post
type PostId = PostId of string

View File

@@ -1,7 +1,28 @@
namespace MyWebLog.ViewModels
open MyWebLog
open System
open System.Collections.Generic
open MyWebLog
/// Details about a category, used to display category lists
[<NoComparison; NoEquality>]
type DisplayCategory =
{ /// The ID of the category
id : string
/// The slug for the category
slug : string
/// The name of the category
name : string
/// A description of the category
description : string option
/// The parent category names for this (sub)category
parentNames : string[]
}
/// Details about a page used to display page lists
[<NoComparison; NoEquality>]
@@ -40,17 +61,6 @@ type DisplayPage =
}
/// The model to use to allow a user to log on
[<CLIMutable; NoComparison; NoEquality>]
type LogOnModel =
{ /// The user's e-mail address
emailAddress : string
/// The user's password
password : string
}
/// The model used to display the admin dashboard
[<NoComparison; NoEquality>]
type DashboardModel =
@@ -74,6 +84,35 @@ type DashboardModel =
}
/// View model for editing categories
[<CLIMutable; NoComparison; NoEquality>]
type EditCategoryModel =
{ /// The ID of the category being edited
categoryId : string
/// The name of the category
name : string
/// The category's URL slug
slug : string
/// A description of the category (optional)
description : string
/// The ID of the category for which this is a subcategory (optional)
parentId : string
}
/// Create an edit model from an existing category
static member fromCategory (cat : Category) =
{ categoryId = CategoryId.toString cat.id
name = cat.name
slug = cat.slug
description = defaultArg cat.description ""
parentId = cat.parentId |> Option.map CategoryId.toString |> Option.defaultValue ""
}
/// View model to edit a page
[<CLIMutable; NoComparison; NoEquality>]
type EditPageModel =
@@ -114,6 +153,85 @@ type EditPageModel =
}
/// The model to use to allow a user to log on
[<CLIMutable; NoComparison; NoEquality>]
type LogOnModel =
{ /// The user's e-mail address
emailAddress : string
/// The user's password
password : string
}
/// View model for posts in a list
[<NoComparison; NoEquality>]
type PostListItem =
{ /// The ID of the post
id : string
/// The ID of the user who authored the post
authorId : string
/// The status of the post
status : string
/// The title of the post
title : string
/// The permalink for the post
permalink : string
/// When this post was published
publishedOn : Nullable<DateTime>
/// When this post was last updated
updatedOn : DateTime
/// The text of the post
text : string
/// The IDs of the categories for this post
categoryIds : string[]
/// Tags for the post
tags : string[]
}
/// Create a post list item from a post
static member fromPost (post : Post) =
{ id = PostId.toString post.id
authorId = WebLogUserId.toString post.authorId
status = PostStatus.toString post.status
title = post.title
permalink = Permalink.toString post.permalink
publishedOn = Option.toNullable post.publishedOn
updatedOn = post.updatedOn
text = post.text
categoryIds = post.categoryIds |> List.map CategoryId.toString |> Array.ofList
tags = Array.ofList post.tags
}
/// View model for displaying posts
type PostDisplay =
{ /// The posts to be displayed
posts : PostListItem[]
/// Category ID -> name lookup
categories : IDictionary<string, string>
/// Author ID -> name lookup
authors : IDictionary<string, string>
/// Whether there are newer posts than the ones in this model
hasNewer : bool
/// Whether there are older posts than the ones in this model
hasOlder : bool
}
/// View model for editing web log settings
[<CLIMutable; NoComparison; NoEquality>]
type SettingsModel =