diff --git a/src/MyWebLog.Tests/Domain/SupportTypesTests.fs b/src/MyWebLog.Tests/Domain/SupportTypesTests.fs index 84a3170..3e3164f 100644 --- a/src/MyWebLog.Tests/Domain/SupportTypesTests.fs +++ b/src/MyWebLog.Tests/Domain/SupportTypesTests.fs @@ -530,6 +530,26 @@ let openGraphTypeTests = testList "OpenGraphType" [ (fun () -> ignore (OpenGraphType.Parse "anthology")) "Invalid value should have raised an exception" } ] + test "Selections succeeds" { + let it = OpenGraphType.Selections + Expect.hasLength it 13 "There should be 13 selections" + Expect.equal (List.head it) ("article", "Article") "Article not found where expected" + Expect.equal (it |> List.item 1) ("book", "Book") "Book not found where expected" + Expect.equal (it |> List.item 2) ("music.album", "Music: Album") "MusicAlbum not found where expected" + Expect.equal (it |> List.item 3) ("music.playlist", "Music: Playlist") "MusicPlaylist not found where expected" + Expect.equal + (it |> List.item 4) + ("music.radio_station", "Music: Radio Station") + "MusicRadioStation not found where expected" + Expect.equal (it |> List.item 5) ("music.song", "Music: Song") "MusicSong not found where expected" + Expect.equal (it |> List.item 6) ("payment.link", "Payment Link") "PaymentLink not found where expected" + Expect.equal (it |> List.item 7) ("profile", "Profile") "Profile not found where expected" + Expect.equal (it |> List.item 8) ("video.episode", "Video: Episode") "VideoEpisode not found where expected" + Expect.equal (it |> List.item 9) ("video.movie", "Video: Movie") "VideoMovie not found where expected" + Expect.equal (it |> List.item 10) ("video.other", "Video: Other") "VideoOther not found where expected" + Expect.equal (it |> List.item 11) ("video.tv_show", "Video: TV Show") "VideoTvShow not found where expected" + Expect.equal (it |> List.item 12) ("website", "Website") "Website not found where expected" + } testList "ToString" [ test "succeeds for Article" { Expect.equal (string Article) "article" "Article string incorrect" diff --git a/src/MyWebLog/Views/Helpers.fs b/src/MyWebLog/Views/Helpers.fs index 8482b71..651e46b 100644 --- a/src/MyWebLog/Views/Helpers.fs +++ b/src/MyWebLog/Views/Helpers.fs @@ -393,7 +393,7 @@ let commonTemplates (model: EditCommonModel) (templates: MetaItem seq) = /// The edit model /// Fields for editing OpenGraph data for a page or post let commonOpenGraph (model: EditCommonModel) = - fieldset [] [ + fieldset [ _class "mb-3" ] [ legend [] [ span [ _class "form-check form-switch" ] [ small [] [ @@ -406,29 +406,45 @@ let commonOpenGraph (model: EditCommonModel) = ] ] div [ _id "og_props"; _class $"""container p-0 collapse{if model.AssignOpenGraph then " show" else ""}""" ] [ - div [ _class "col-4" ] [ - selectField [ _required ] (nameof model.OpenGraphType) "Type" model.OpenGraphType - OpenGraphType.Selections fst snd [] + fieldset [ _id "og_item" ] [ + legend [] [ raw "Item Details" ] + div [ _class "row p-0" ] [ + div [ _class "mb-3 col-xs-6 col-md-3" ] [ + selectField [ _required ] (nameof model.OpenGraphType) "Type" model.OpenGraphType + OpenGraphType.Selections fst snd [] + ] + div [ _class "mb-3 col-xs-6 col-md-3" ] [ + textField [] (nameof model.OpenGraphLocale) "Locale" model.OpenGraphLocale + [ span [ _class "form-text" ] [ raw "ex. en-US" ] ] + ] + div [ _class "mb-3 col-xs-6 col-md-4" ] [ + textField [] (nameof model.OpenGraphAlternateLocales) "Alternate Locales" + model.OpenGraphAlternateLocales + [ span [ _class "form-text" ] [ raw "comma separated" ] ] + ] + div [ _class "mb-3 col-xs-6 col-md-2" ] [ + textField [] (nameof model.OpenGraphDeterminer) "Determiner" model.OpenGraphDeterminer + [ span [ _class "form-text" ] [ raw "a/an/the"; br []; raw "(blank = auto)" ] ] + ] + div [ _class "mb-3 col-12" ] [ + textField [] (nameof model.OpenGraphDescription) "Short Description" model.OpenGraphDescription + [] + ] + ] + // member val OpenGraphImageUrl = "" with get, set + // member val OpenGraphImageType = "" with get, set + // member val OpenGraphImageWidth = "" with get, set + // member val OpenGraphImageHeight = "" with get, set + // member val OpenGraphImageAlt = "" with get, set + // member val OpenGraphAudioUrl = "" with get, set + // member val OpenGraphAudioType = "" with get, set + // member val OpenGraphVideoUrl = "" with get, set + // member val OpenGraphVideoType = "" with get, set + // member val OpenGraphVideoWidth = "" with get, set + // member val OpenGraphVideoHeight = "" with get, set + // member val OpenGraphExtraNames: string array = [||] with get, set + // member val OpenGraphExtraValues: string array = [||] with get, set ] - // member val OpenGraphType = "" with get, set - // member val OpenGraphImageUrl = "" with get, set - // member val OpenGraphImageType = "" with get, set - // member val OpenGraphImageWidth = "" with get, set - // member val OpenGraphImageHeight = "" with get, set - // member val OpenGraphImageAlt = "" with get, set - // member val OpenGraphAudioUrl = "" with get, set - // member val OpenGraphAudioType = "" with get, set - // member val OpenGraphDescription = "" with get, set - // member val OpenGraphDeterminer = "" with get, set - // member val OpenGraphLocale = "" with get, set - // member val OpenGraphAlternateLocales = "" with get, set - // member val OpenGraphVideoUrl = "" with get, set - // member val OpenGraphVideoType = "" with get, set - // member val OpenGraphVideoWidth = "" with get, set - // member val OpenGraphVideoHeight = "" with get, set - // member val OpenGraphExtraNames: string array = [||] with get, set - // member val OpenGraphExtraValues: string array = [||] with get, set - ] ] diff --git a/src/admin-theme/wwwroot/admin.js b/src/admin-theme/wwwroot/admin.js index 31baf7c..813a68f 100644 --- a/src/admin-theme/wwwroot/admin.js +++ b/src/admin-theme/wwwroot/admin.js @@ -13,7 +13,7 @@ this.Admin = { * @type {number} */ nextPermalink : 0, - + /** * Set the next meta item index * @param {number} idx The index to set @@ -44,23 +44,23 @@ this.Admin = { const removeCol = document.createElement("div") removeCol.className = "col-1 text-center align-self-center" removeCol.appendChild(removeBtn) - + return removeCol }, - + /** * Create a metadata name field * @returns {HTMLInputElement} The name input element */ createMetaNameField() { const nameField = document.createElement("input") - + nameField.type = "text" nameField.name = "MetaNames" nameField.id = `metaNames_${this.nextMetaIndex}` nameField.className = "form-control" nameField.placeholder = "Name" - + return nameField }, @@ -82,7 +82,7 @@ this.Admin = { const nameCol = document.createElement("div") nameCol.className = "col-3" nameCol.appendChild(nameFloat) - + return nameCol }, @@ -92,13 +92,13 @@ this.Admin = { */ createMetaValueField() { const valueField = document.createElement("input") - + valueField.type = "text" valueField.name = "MetaValues" valueField.id = `metaValues_${this.nextMetaIndex}` valueField.className = "form-control" valueField.placeholder = "Value" - + return valueField }, @@ -124,11 +124,11 @@ this.Admin = { valueHint.innerText = hintText valueFloat.appendChild(valueHint) } - + const valueCol = document.createElement("div") valueCol.className = "col-8" valueCol.appendChild(valueFloat) - + return valueCol }, @@ -149,18 +149,18 @@ this.Admin = { document.getElementById("meta_items").appendChild(newRow) this.nextMetaIndex++ }, - + /** * Add a new row for metadata entry */ addMetaItem() { const nameField = this.createMetaNameField() - + this.createMetaRow( this.createMetaRemoveColumn(), this.createMetaNameColumn(nameField), this.createMetaValueColumn(this.createMetaValueField(), undefined)) - + document.getElementById(nameField.id).focus() }, @@ -226,7 +226,16 @@ this.Admin = { const link = document.getElementById("ChapterEditLink") if (link) link.style.display = src === "none" || src === "external" ? "none" : "" }, - + + /** + * Enable or disable OpenGraph fields + */ + toggleOpenGraphFields() { + const disabled = !document.getElementById("AssignOpenGraph").checked + let fieldsets = ["og_item"] + fieldsets.forEach(it => document.getElementById(it).disabled = disabled) + }, + /** * Enable or disable podcast fields */ @@ -244,7 +253,7 @@ this.Admin = { } fields.forEach(it => document.getElementById(it).disabled = disabled) }, - + /** * Check to enable or disable podcast fields */ @@ -263,7 +272,7 @@ this.Admin = { elt.innerText = "Copied" return false }, - + /** * Toggle the source of a custom RSS feed * @param {string} source The source that was selected @@ -281,7 +290,7 @@ this.Admin = { tagInput.disabled = false } }, - + /** * Remove a metadata item * @param {number} idx The index of the metadata item to remove @@ -326,12 +335,12 @@ this.Admin = { msgs.forEach(msg => { const parts = msg.split("|||") if (parts.length < 2) return - + // Create the toast header const toastType = document.createElement("strong") toastType.className = "me-auto text-uppercase" toastType.innerText = parts[0] === "danger" ? "error" : parts[0] - + const closeBtn = document.createElement("button") closeBtn.type = "button" closeBtn.className = "btn-close" @@ -350,7 +359,7 @@ this.Admin = { if (parts.length === 3) { toastBody.innerHTML += `
${parts[2]}` } - + // Assemble the toast const toast = document.createElement("div") toast.className = "toast" @@ -361,10 +370,10 @@ this.Admin = { toast.appendChild(toastBody) document.getElementById("toasts").appendChild(toast) - + let options = { delay: 4000 } if (parts[0] !== "success") options.autohide = false - + const theToast = new bootstrap.Toast(toast, options) theToast.show() })