First cut of common edit model

This commit is contained in:
Daniel J. Summers 2024-03-15 18:03:38 -04:00
parent 3998399e11
commit ddab491dfc
3 changed files with 90 additions and 4 deletions

View File

@ -604,6 +604,59 @@ type EditMyInfoModel = {
NewPasswordConfirm = "" }
/// View model common to page and post edits
type EditCommonModel() =
/// Find the latest revision within a list of revisions
let findLatestRevision (revs: Revision list) =
match revs |> List.sortByDescending _.AsOf |> List.tryHead with Some rev -> rev | None -> Revision.Empty
/// The ID of the page or post
member val Id = "" with get, set
/// The title of the page or post
member val Title = "" with get, set
/// The permalink for the page or post
member val Permalink = "" with get, set
/// The entity to which this model applies ("page" or "post")
member val Entity = "" with get, set
/// Whether to provide a link to manage chapters
member val IncludeChapterLink = false with get, set
/// The source type ("HTML" or "Markdown")
member val Source = "" with get, set
/// The text of the page or post
member val Text = "" with get, set
/// Whether this is a new page or post
member this.IsNew with get () = this.Id = "new"
/// Fill the properties of this object from a page
member this.FromPage (page: Page) =
let latest = findLatestRevision page.Revisions
this.Id <- string page.Id
this.Title <- page.Title
this.Permalink <- string page.Permalink
this.Entity <- "page"
this.Source <- latest.Text.SourceType
this.Text <- latest.Text.Text
/// Fill the properties of this object from a post
member this.FromPost (post: Post) =
let latest = findLatestRevision post.Revisions
this.Id <- string post.Id
this.Title <- post.Title
this.Permalink <- string post.Permalink
this.Entity <- "post"
this.IncludeChapterLink <- Option.isSome post.Episode && Option.isSome post.Episode.Value.Chapters
this.Source <- latest.Text.SourceType
this.Text <- latest.Text.Text
/// View model to edit a page
[<CLIMutable; NoComparison; NoEquality>]
type EditPageModel = {

View File

@ -228,10 +228,9 @@ let register () =
typeof<CustomFeed>; typeof<Episode>; typeof<Episode option>; typeof<MetaItem>; typeof<Page>
typeof<RedirectRule>; typeof<RssOptions>; typeof<TagMap>; typeof<UploadDestination>; typeof<WebLog>
// View models
typeof<AppViewContext>; typeof<DisplayCategory>; typeof<DisplayCustomFeed>; typeof<DisplayPage>
typeof<DisplayTheme>; typeof<DisplayUpload>; typeof<DisplayUser>; typeof<EditCategoryModel>
typeof<EditCustomFeedModel>; typeof<EditPageModel>; typeof<EditPostModel>; typeof<EditRssModel>
typeof<PostDisplay>; typeof<PostListItem>; typeof<SettingsModel>; typeof<UserMessage>
typeof<AppViewContext>; typeof<DisplayCategory>; typeof<DisplayCustomFeed>; typeof<DisplayPage>
typeof<DisplayTheme>; typeof<DisplayUpload>; typeof<DisplayUser>; typeof<EditPageModel>
typeof<EditPostModel>; typeof<PostDisplay>; typeof<PostListItem>; typeof<UserMessage>
// Framework types
typeof<AntiforgeryTokenSet>; typeof<DateTime option>; typeof<int option>; typeof<KeyValuePair>
typeof<MetaItem list>; typeof<string list>; typeof<string option>; typeof<TagMap list>

View File

@ -310,6 +310,40 @@ let roundTrip = InstantPattern.CreateWithInvariantCulture "uuuu'-'MM'-'dd'T'HH':
let private capitalize (it: string) =
$"{(string it[0]).ToUpper()}{it[1..]}"
/// The common edit form shared by pages and posts
let commonEdit (model: EditCommonModel) app = [
textField [ _required; _autofocus ] (nameof model.Title) "Title" model.Title []
textField [ _required ] (nameof model.Permalink) "Permalink" model.Permalink [
if not model.IsNew then
let urlBase = relUrl app $"admin/{model.Entity}/{model.Id}"
span [ _class "form-text" ] [
a [ _href $"{urlBase}/permalinks" ] [ raw "Manage Permalinks" ]; actionSpacer
a [ _href $"{urlBase}/revisions" ] [ raw "Manage Revisions" ]
if model.IncludeChapterLink then
span [ _id "chapterEditLink" ] [
actionSpacer; a [ _href $"{urlBase}/chapters" ] [ raw "Manage Chapters" ]
]
]
]
div [ _class "mb-2" ] [
label [ _for "text" ] [ raw "Text" ]; raw " &nbsp; &nbsp; "
div [ _class "btn-group btn-group-sm"; _roleGroup; _ariaLabel "Text format button group" ] [
input [ _type "radio"; _name (nameof model.Source); _id "source_html"; _class "btn-check"
_value (string Html); if model.Source = string Html then _checked ]
label [ _class "btn btn-sm btn-outline-secondary"; _for "source_html" ] [ raw "HTML" ]
input [ _type "radio"; _name (nameof model.Source); _id "source_md"; _class "btn-check"
_value (string Markdown); if model.Source = string Markdown then _checked ]
label [ _class "btn btn-sm btn-outline-secondary"; _for "source_md" ] [ raw "Markdown" ]
]
]
div [ _class "pb-3" ] [
textarea [ _name (nameof model.Text); _id (nameof model.Text); _class "form-control"; _rows "20" ] [
raw model.Text
]
]
]
/// Form to manage permalinks for pages or posts
let managePermalinks (model: ManagePermalinksModel) app = [
let baseUrl = relUrl app $"admin/{model.Entity}/"