diff --git a/src/MyWebLog.Domain/ViewModels.fs b/src/MyWebLog.Domain/ViewModels.fs index 1e802aa..3632963 100644 --- a/src/MyWebLog.Domain/ViewModels.fs +++ b/src/MyWebLog.Domain/ViewModels.fs @@ -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 [] type EditPageModel = { diff --git a/src/MyWebLog/DotLiquidBespoke.fs b/src/MyWebLog/DotLiquidBespoke.fs index fe1c9d7..872486b 100644 --- a/src/MyWebLog/DotLiquidBespoke.fs +++ b/src/MyWebLog/DotLiquidBespoke.fs @@ -228,10 +228,9 @@ let register () = typeof; typeof; typeof; typeof; typeof typeof; typeof; typeof; typeof; typeof // View models - typeof; typeof; typeof; typeof - typeof; typeof; typeof; typeof - typeof; typeof; typeof; typeof - typeof; typeof; typeof; typeof + typeof; typeof; typeof; typeof + typeof; typeof; typeof; typeof + typeof; typeof; typeof; typeof // Framework types typeof; typeof; typeof; typeof typeof; typeof; typeof; typeof diff --git a/src/MyWebLog/Views/Helpers.fs b/src/MyWebLog/Views/Helpers.fs index a087d2c..23213c0 100644 --- a/src/MyWebLog/Views/Helpers.fs +++ b/src/MyWebLog/Views/Helpers.fs @@ -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 "     " + 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}/"