Add native font stack to pref page (#38)
- Update font verbiage to explain native fonts - Sync/update missing/outdated resources
This commit is contained in:
parent
24f5b5a741
commit
1b48acd66a
@ -11,7 +11,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Giraffe" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.FSharpLu" Version="0.11.7" />
|
||||
<PackageReference Include="NodaTime" Version="3.1.1" />
|
||||
<PackageReference Update="FSharp.Core" Version="6.0.5" />
|
||||
<PackageReference Include="Npgsql.FSharp" Version="5.3.0" />
|
||||
|
@ -114,11 +114,11 @@ let listPreferencesTests =
|
||||
Expect.equal mt.DaysToKeepNew 7 "The default days to keep new should have been 7"
|
||||
Expect.equal mt.LongTermUpdateWeeks 4 "The default long term update weeks should have been 4"
|
||||
Expect.equal mt.EmailFromName "PrayerTracker" "The default e-mail from name should have been PrayerTracker"
|
||||
Expect.equal mt.EmailFromAddress "prayer@djs-consulting.com"
|
||||
"The default e-mail from address should have been prayer@djs-consulting.com"
|
||||
Expect.equal mt.EmailFromAddress "prayer@bitbadger.solutions"
|
||||
"The default e-mail from address should have been prayer@bitbadger.solutions"
|
||||
Expect.equal mt.Fonts "native" "The default list fonts were incorrect"
|
||||
Expect.equal mt.HeadingColor "maroon" "The default heading text color should have been maroon"
|
||||
Expect.equal mt.LineColor "navy" "The default heding line color should have been navy"
|
||||
Expect.equal mt.LineColor "navy" "The default heading line color should have been navy"
|
||||
Expect.equal mt.HeadingFontSize 16 "The default heading font size should have been 16"
|
||||
Expect.equal mt.TextFontSize 12 "The default text font size should have been 12"
|
||||
Expect.equal mt.RequestSort SortByDate "The default request sort should have been by date"
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Expecto" Version="9.0.4" />
|
||||
<PackageReference Include="NodaTime.Testing" Version="3.1.0" />
|
||||
<PackageReference Include="NodaTime.Testing" Version="3.1.1" />
|
||||
<PackageReference Update="FSharp.Core" Version="6.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -261,7 +261,7 @@ let editMemberTests =
|
||||
[<Tests>]
|
||||
let editPreferencesTests =
|
||||
testList "EditPreferences" [
|
||||
test "fromPreferences succeeds for named colors and private list" {
|
||||
test "fromPreferences succeeds for native fonts, named colors, and private list" {
|
||||
let prefs = ListPreferences.empty
|
||||
let edit = EditPreferences.fromPreferences prefs
|
||||
Expect.equal edit.ExpireDays prefs.DaysToExpire "The expiration days were not filled correctly"
|
||||
@ -278,7 +278,8 @@ let editPreferencesTests =
|
||||
Expect.equal edit.LineColor prefs.LineColor "The heading line color was not filled correctly"
|
||||
Expect.equal edit.HeadingColorType "Name" "The heading text color type was not derived correctly"
|
||||
Expect.equal edit.HeadingColor prefs.HeadingColor "The heading text color was not filled correctly"
|
||||
Expect.equal edit.Fonts prefs.Fonts "The list fonts were not filled correctly"
|
||||
Expect.isTrue edit.IsNative "The IsNative flag should have been true (default value)"
|
||||
Expect.isNone edit.Fonts "The list fonts should not exist for native font stack"
|
||||
Expect.equal edit.HeadingFontSize prefs.HeadingFontSize "The heading font size was not filled correctly"
|
||||
Expect.equal edit.ListFontSize prefs.TextFontSize "The list text font size was not filled correctly"
|
||||
Expect.equal edit.TimeZone (TimeZoneId.toString prefs.TimeZoneId) "The time zone was not filled correctly"
|
||||
@ -310,6 +311,13 @@ let editPreferencesTests =
|
||||
Expect.equal edit.Visibility GroupVisibility.PublicList
|
||||
"The list visibility was not derived correctly"
|
||||
}
|
||||
test "fromPreferences succeeds for non-native fonts" {
|
||||
let prefs = { ListPreferences.empty with Fonts = "Arial,sans-serif" }
|
||||
let edit = EditPreferences.fromPreferences prefs
|
||||
Expect.isFalse edit.IsNative "The IsNative flag should have been false"
|
||||
Expect.isSome edit.Fonts "The fonts should have been filled for non-native fonts"
|
||||
Expect.equal edit.Fonts.Value prefs.Fonts "The fonts were not filled correctly"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
@ -529,11 +537,12 @@ let requestListTests =
|
||||
"AsHtml succeeds without header or as-of date",
|
||||
fun reqList ->
|
||||
let htmlList = { reqList with SmallGroup = { reqList.SmallGroup with Name = "Test HTML Group" } }
|
||||
let html = htmlList.AsHtml _s
|
||||
let html = htmlList.AsHtml _s
|
||||
let fonts = reqList.SmallGroup.Preferences.FontStack.Replace ("\"", """)
|
||||
Expect.equal -1 (html.IndexOf "Test HTML Group")
|
||||
"The small group name should not have existed (no header)"
|
||||
let curReqHeading =
|
||||
[ """<table style="font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;page-break-inside:avoid;">"""
|
||||
[ $"""<table style="font-family:{fonts};page-break-inside:avoid;">"""
|
||||
"<tr>"
|
||||
"""<td style="font-size:16pt;color:maroon;padding:3px 0;border-top:solid 3px navy;border-bottom:solid 3px navy;font-weight:bold;">"""
|
||||
" Current Requests </td></tr></table>"
|
||||
@ -541,16 +550,16 @@ let requestListTests =
|
||||
|> String.concat ""
|
||||
Expect.stringContains html curReqHeading """Heading for category "Current Requests" not found"""
|
||||
let curReqHtml =
|
||||
[ "<ul>"
|
||||
"""<li style="list-style-type:circle;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;font-size:12pt;padding-bottom:.25em;">"""
|
||||
[ $"""<ul style="font-family:{fonts};font-size:12pt">"""
|
||||
"""<li style="list-style-type:circle;padding-bottom:.25em;">"""
|
||||
"<strong>Zeb</strong> – zyx</li>"
|
||||
"""<li style="list-style-type:disc;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;font-size:12pt;padding-bottom:.25em;">"""
|
||||
"""<li style="list-style-type:disc;padding-bottom:.25em;">"""
|
||||
"<strong>Aaron</strong> – abc</li></ul>"
|
||||
]
|
||||
|> String.concat ""
|
||||
Expect.stringContains html curReqHtml """Expected HTML for "Current Requests" requests not found"""
|
||||
let praiseHeading =
|
||||
[ """<table style="font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;page-break-inside:avoid;">"""
|
||||
[ $"""<table style="font-family:{fonts};page-break-inside:avoid;">"""
|
||||
"<tr>"
|
||||
"""<td style="font-size:16pt;color:maroon;padding:3px 0;border-top:solid 3px navy;border-bottom:solid 3px navy;font-weight:bold;">"""
|
||||
" Praise Reports </td></tr></table>"
|
||||
@ -558,8 +567,8 @@ let requestListTests =
|
||||
|> String.concat ""
|
||||
Expect.stringContains html praiseHeading """Heading for category "Praise Reports" not found"""
|
||||
let praiseHtml =
|
||||
[ "<ul>"
|
||||
"""<li style="list-style-type:circle;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif;font-size:12pt;padding-bottom:.25em;">"""
|
||||
[ $"""<ul style="font-family:{fonts};font-size:12pt">"""
|
||||
"""<li style="list-style-type:circle;padding-bottom:.25em;">"""
|
||||
"nmo</li></ul>"
|
||||
]
|
||||
|> String.concat ""
|
||||
@ -571,9 +580,10 @@ let requestListTests =
|
||||
SmallGroup = { reqList.SmallGroup with Name = "Test HTML Group" }
|
||||
ShowHeader = true
|
||||
}
|
||||
let html = htmlList.AsHtml _s
|
||||
let html = htmlList.AsHtml _s
|
||||
let fonts = reqList.SmallGroup.Preferences.FontStack.Replace ("\"", """)
|
||||
let lstHeading =
|
||||
[ """<div style="text-align:center;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif">"""
|
||||
[ $"""<div style="text-align:center;font-family:{fonts}">"""
|
||||
"""<span style="font-size:16pt;"><strong>Prayer Requests</strong></span><br>"""
|
||||
"""<span style="font-size:12pt;"><strong>Test HTML Group</strong><br>"""
|
||||
htmlList.Date.ToString ("MMMM d, yyyy", null)
|
||||
|
@ -41,12 +41,14 @@ let edit (model : EditChurch) ctx viewInfo =
|
||||
div [ _checkboxField ] [
|
||||
inputField "checkbox" (nameof model.HasInterface) "True"
|
||||
[ if defaultArg model.HasInterface false then _checked ]
|
||||
label [ _for (nameof model.HasInterface) ] [ locStr s["Has an interface with Virtual Prayer Room"] ]
|
||||
label [ _for (nameof model.HasInterface) ] [
|
||||
locStr s["Has an Interface with “{0}”", "Virtual Prayer Space"]
|
||||
]
|
||||
]
|
||||
]
|
||||
div [ _fieldRowWith [ "pt-fadeable" ]; _id "divInterfaceAddress" ] [
|
||||
div [ _inputField ] [
|
||||
label [ _for (nameof model.InterfaceAddress) ] [ locStr s["VPR Interface URL"] ]
|
||||
label [ _for (nameof model.InterfaceAddress) ] [ locStr s["Interface URL"] ]
|
||||
inputField "url" (nameof model.InterfaceAddress) (defaultArg model.InterfaceAddress "") []
|
||||
]
|
||||
]
|
||||
|
@ -302,11 +302,12 @@ let private contentSection viewInfo pgTitle (content : XmlNode) = [
|
||||
htmlFooter viewInfo
|
||||
match viewInfo.OnLoadScript with
|
||||
| Some onLoad ->
|
||||
let doCall = if onLoad.EndsWith ")" then "" else "()"
|
||||
script [] [
|
||||
rawText $"""
|
||||
window.doOnLoad = () => {{
|
||||
if (window.PT) {{
|
||||
{onLoad}()
|
||||
{onLoad}{doCall}
|
||||
delete window.doOnLoad
|
||||
}} else {{ setTimeout(window.doOnLoad, 500) }}
|
||||
}}
|
||||
|
@ -54,15 +54,10 @@ let edit (model : EditRequest) today ctx viewInfo =
|
||||
div [ _fieldRow ] [
|
||||
div [ _inputField ] [
|
||||
label [] [ locStr s["Expiration"] ]
|
||||
ReferenceList.expirationList s (not model.IsNew)
|
||||
|> List.map (fun exp ->
|
||||
let radioId = String.concat "_" [ nameof model.Expiration; fst exp ]
|
||||
span [ _class "text-nowrap" ] [
|
||||
radio (nameof model.Expiration) radioId (fst exp) model.Expiration
|
||||
label [ _for radioId ] [ space; locStr (snd exp) ]
|
||||
rawText " "
|
||||
])
|
||||
|> div [ _class "pt-center-text" ]
|
||||
span [ _class "pt-radio-group" ] [
|
||||
for code, name in ReferenceList.expirationList s (not model.IsNew) do
|
||||
label [] [ radio (nameof model.Expiration) "" code model.Expiration; locStr name ]
|
||||
]
|
||||
]
|
||||
]
|
||||
div [ _fieldRow ] [
|
||||
|
@ -396,8 +396,8 @@
|
||||
<data name="The group member “{0}” was deleted successfully" xml:space="preserve">
|
||||
<value>El miembro del grupo “{0}” se eliminó con éxito</value>
|
||||
</data>
|
||||
<data name="The group {0} and its {1} prayer request(s) was deleted successfully (revoked access from {2} user(s))" xml:space="preserve">
|
||||
<value>El grupo {0} y sus {1} peticion(es) de oración se ha eliminado correctamente (acceso revocada por {2} usuario(s))</value>
|
||||
<data name="The group “{0}” and its {1} prayer request(s) were deleted successfully; revoked access from {2} user(s)" xml:space="preserve">
|
||||
<value>El grupo “{0}” y sus {1} peticion(es) de oración se ha eliminado correctamente; acceso revocada por {2} usuario(s)</value>
|
||||
</data>
|
||||
<data name="The old password was incorrect - your password was NOT changed" xml:space="preserve">
|
||||
<value>La contraseña antigua es incorrecta - la contraseña NO ha cambiado</value>
|
||||
@ -742,7 +742,7 @@
|
||||
<value>Este</value>
|
||||
</data>
|
||||
<data name="MMMM d, yyyy" xml:space="preserve">
|
||||
<value>d \de MMMM yyyy</value>
|
||||
<value>d \d\e MMMM yyyy</value>
|
||||
</data>
|
||||
<data name="Mountain" xml:space="preserve">
|
||||
<value>Montaña</value>
|
||||
@ -831,4 +831,55 @@
|
||||
<data name="Administrators" xml:space="preserve">
|
||||
<value>Administradores</value>
|
||||
</data>
|
||||
<data name="Native Fonts" xml:space="preserve">
|
||||
<value>Fuentes Nativas</value>
|
||||
</data>
|
||||
<data name="Named Fonts" xml:space="preserve">
|
||||
<value>Fuentes con Nombre</value>
|
||||
</data>
|
||||
<data name="Select Church" xml:space="preserve">
|
||||
<value>Seleccione una Iglesia</value>
|
||||
</data>
|
||||
<data name="Select Group" xml:space="preserve">
|
||||
<value>Seleccione un Grupo</value>
|
||||
</data>
|
||||
<data name="Member Name" xml:space="preserve">
|
||||
<value>Nombre de Miembro</value>
|
||||
</data>
|
||||
<data name="Custom Color" xml:space="preserve">
|
||||
<value>Color Personalizado</value>
|
||||
</data>
|
||||
<data name="Church Name" xml:space="preserve">
|
||||
<value>Nombre de la Iglesia</value>
|
||||
</data>
|
||||
<data name="City" xml:space="preserve">
|
||||
<value>Ciudad</value>
|
||||
</data>
|
||||
<data name="Has an Interface with “{0}”" xml:space="preserve">
|
||||
<value>Tiene una Interfaz con “{0}”</value>
|
||||
</data>
|
||||
<data name="Interface URL" xml:space="preserve">
|
||||
<value>URL de la Interfaz</value>
|
||||
</data>
|
||||
<data name="Successfully {0} church “{1}”" xml:space="preserve">
|
||||
<value>Iglesia “{1}” {0} con éxito</value>
|
||||
</data>
|
||||
<data name="The church “{0}” and its {1} small group(s) (with {2} prayer request(s)) were deleted successfully; revoked access from {3} user(s)" xml:space="preserve">
|
||||
<value>La iglesia "{0}" y sus {1} grupo(s) (con {2} peticion(es) de oración) se eliminaron correctamente; acceso revocado de {3} usuario(s)</value>
|
||||
</data>
|
||||
<data name="Successfully {0} group “{1}”" xml:space="preserve">
|
||||
<value>El grupo “{1}” {0} con éxito</value>
|
||||
</data>
|
||||
<data name="First Name" xml:space="preserve">
|
||||
<value>Primer Nombre</value>
|
||||
</data>
|
||||
<data name="Last Name" xml:space="preserve">
|
||||
<value>Apellido</value>
|
||||
</data>
|
||||
<data name="Password Again" xml:space="preserve">
|
||||
<value>Contraseña otra Vez</value>
|
||||
</data>
|
||||
<data name="This User Is a {0} Administrator" xml:space="preserve">
|
||||
<value>Este Usuario Es un Administrador de {0}</value>
|
||||
</data>
|
||||
</root>
|
@ -117,16 +117,16 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Ending with either “serif” or “sans-serif” will cause the user's browser to use the default “serif” font (“Times New Roman” on Windows) or “sans-serif” font (“Arial” on Windows) if no other fonts in the list are found." xml:space="preserve">
|
||||
<value>Con la extensión “serif” o el “sans-serif” hará que el navegador del usuario para utilizar el valor predeterminado “serif” de la fuente (“Times New Roman” en Windows) o “sans-serif” de la fuente (“Arial” en Windows) si no otras fuentes en la lista se encuentran.</value>
|
||||
<data name="Ending this list with either “serif” or “sans-serif” will cause the user's browser to use the default “serif” font (“Times New Roman” on Windows) or “sans-serif” font (“Arial” on Windows) if no other fonts in the list are found." xml:space="preserve">
|
||||
<value>Terminar esta lista con “serif” o “sans-serif” hará que el navegador del usuario utilice la fuente predeterminado “serif” (“Times New Roman” en Windows) o “sans-serif” (“Arial” en Windows) si no se encuentran otras fuentes en la lista.</value>
|
||||
</data>
|
||||
<data name="If you want a custom color, you may be able to get some ideas (and a list of RGB values for those colors) from the W3 School's <a href="http://www.w3schools.com/html/html_colornames.asp" title="HTML Color List - W3 School">HTML color name list</a>." xml:space="preserve">
|
||||
<value>Si desea un color personalizado, que puede ser capaz de obtener algunas ideas (y una lista de valores RGB para los colores) de la lista de la Escuela de W3 de <a href="http://www.w3schools.com/html/html_colornames.asp" title="La Lista de Nombres de Colores HTML - La Escuela de W3">nombres de colores HTML</a>.</value>
|
||||
</data>
|
||||
<data name="List font names, separated by commas." xml:space="preserve">
|
||||
<value>Lista de nombres de fuentes separados por comas.</value>
|
||||
<data name="Native fonts match the default font based on the user's device (computer, phone, tablet, etc.)." xml:space="preserve">
|
||||
<value>Las fuentes nativas coinciden con la fuente predeterminada según el dispositivo del usuario (computadora, teléfono, tableta, etc.).</value>
|
||||
</data>
|
||||
<data name="The first font that is matched is the one that is used." xml:space="preserve">
|
||||
<value>La primera fuente que se corresponde es el que se utiliza.</value>
|
||||
<data name="Named fonts should be separated by commas, and will be displayed using the first one the user has in the list." xml:space="preserve">
|
||||
<value>Las fuentes con nombre deben estar separadas por comas y se mostrarán usando la primera que el usuario tenga en la lista.</value>
|
||||
</data>
|
||||
</root>
|
@ -30,13 +30,15 @@ let announcement isAdmin ctx viewInfo =
|
||||
div [ _fieldRow ] [
|
||||
div [ _inputField ] [
|
||||
label [] [ locStr s["Send Announcement to"]; rawText ":" ]
|
||||
div [ _class "pt-center-text" ] [
|
||||
radio (nameof model.SendToClass) $"{nameof model.SendToClass}_Y" "Y" "Y"
|
||||
label [ _for $"{nameof model.SendToClass}_Y" ] [
|
||||
locStr s["This Group"]; rawText " "
|
||||
div [ _class "pt-radio-group" ] [
|
||||
label [] [
|
||||
radio (nameof model.SendToClass) $"{nameof model.SendToClass}_Y" "Y" "Y"
|
||||
locStr s["This Group"]
|
||||
]
|
||||
label [] [
|
||||
radio (nameof model.SendToClass) $"{nameof model.SendToClass}_N" "N" "Y"
|
||||
locStr s["All {0} Users", s["PrayerTracker"]]
|
||||
]
|
||||
radio (nameof model.SendToClass) $"{nameof model.SendToClass}_N" "N" "Y"
|
||||
label [ _for $"{nameof model.SendToClass}_N" ] [ locStr s["All {0} Users", s["PrayerTracker"]] ]
|
||||
]
|
||||
]
|
||||
]
|
||||
@ -519,7 +521,21 @@ let preferences (model : EditPreferences) ctx viewInfo =
|
||||
legend [] [ strong [] [ icon "font_download"; rawText " "; locStr s["Fonts"] ] ]
|
||||
div [ _inputField ] [
|
||||
label [ _for (nameof model.Fonts) ] [ locStr s["Fonts** for List"] ]
|
||||
inputField "text" (nameof model.Fonts) model.Fonts [ _required ]
|
||||
let value = if model.IsNative then "True" else "False"
|
||||
span [ _class "pt-radio-group" ] [
|
||||
label [] [
|
||||
radio (nameof model.IsNative) $"{nameof model.IsNative}_Y" "True" value
|
||||
locStr s["Native Fonts"]
|
||||
]
|
||||
inputField "text" "nativeFontSpacer" "" [ _style "visibility:hidden" ]
|
||||
]
|
||||
span [ _class "pt-radio-group" ] [
|
||||
label [] [
|
||||
radio (nameof model.IsNative) $"{nameof model.IsNative}_N" "False" value
|
||||
locStr s["Named Fonts"]
|
||||
]
|
||||
inputField "text" (nameof model.Fonts) (defaultArg model.Fonts "") [ _required ]
|
||||
]
|
||||
]
|
||||
div [ _fieldRow ] [
|
||||
div [ _inputField ] [
|
||||
@ -595,11 +611,11 @@ let preferences (model : EditPreferences) ctx viewInfo =
|
||||
]
|
||||
p [] [
|
||||
rawText "** "
|
||||
raw l["List font names, separated by commas."]
|
||||
raw l["Native fonts match the default font based on the user's device (computer, phone, tablet, etc.)."]
|
||||
space
|
||||
raw l["The first font that is matched is the one that is used."]
|
||||
raw l["Named fonts should be separated by commas, and will be displayed using the first one the user has in the list."]
|
||||
space
|
||||
raw l["Ending with either “serif” or “sans-serif” will cause the user's browser to use the default “serif” font (“Times New Roman” on Windows) or “sans-serif” font (“Arial” on Windows) if no other fonts in the list are found."]
|
||||
raw l["Ending this list with either “serif” or “sans-serif” will cause the user's browser to use the default “serif” font (“Times New Roman” on Windows) or “sans-serif” font (“Arial” on Windows) if no other fonts in the list are found."]
|
||||
]
|
||||
p [] [
|
||||
rawText "*** "
|
||||
|
@ -133,7 +133,7 @@ let edit (model : EditUser) ctx viewInfo =
|
||||
]
|
||||
div [ _checkboxField ] [
|
||||
inputField "checkbox" (nameof model.IsAdmin) "True" [ if defaultArg model.IsAdmin false then _checked ]
|
||||
label [ _for (nameof model.IsAdmin) ] [ locStr s["This user is a PrayerTracker administrator"] ]
|
||||
label [ _for (nameof model.IsAdmin) ] [ locStr s["This User Is a {0} Administrator", s["PrayerTracker"]] ]
|
||||
]
|
||||
div [ _fieldRow ] [ submit [] "save" s["Save User"] ]
|
||||
]
|
||||
|
@ -374,8 +374,11 @@ type EditPreferences =
|
||||
/// The named color for the heading text
|
||||
HeadingColor : string
|
||||
|
||||
/// Whether the class uses the native font stack
|
||||
IsNative : bool
|
||||
|
||||
/// The fonts to use for the list
|
||||
Fonts : string
|
||||
Fonts : string option
|
||||
|
||||
/// The font size for the heading text
|
||||
HeadingFontSize : int
|
||||
@ -416,7 +419,7 @@ with
|
||||
DefaultEmailType = EmailFormat.fromCode this.DefaultEmailType
|
||||
LineColor = this.LineColor
|
||||
HeadingColor = this.HeadingColor
|
||||
Fonts = this.Fonts
|
||||
Fonts = if this.IsNative || Option.isNone this.Fonts then "native" else this.Fonts.Value
|
||||
HeadingFontSize = this.HeadingFontSize
|
||||
TextFontSize = this.ListFontSize
|
||||
TimeZoneId = TimeZoneId this.TimeZone
|
||||
@ -442,7 +445,8 @@ module EditPreferences =
|
||||
LineColor = prefs.LineColor
|
||||
HeadingColorType = setType prefs.HeadingColor
|
||||
HeadingColor = prefs.HeadingColor
|
||||
Fonts = prefs.Fonts
|
||||
IsNative = (prefs.Fonts = "native")
|
||||
Fonts = if prefs.Fonts = "native" then None else Some prefs.Fonts
|
||||
HeadingFontSize = prefs.HeadingFontSize
|
||||
ListFontSize = prefs.TextFontSize
|
||||
TimeZone = TimeZoneId.toString prefs.TimeZoneId
|
||||
@ -804,7 +808,7 @@ with
|
||||
reqs
|
||||
|> List.map (fun req ->
|
||||
let bullet = if this.IsNew req then "circle" else "disc"
|
||||
li [ _style $"list-style-type:{bullet};font-family:{p.FontStack};font-size:%i{p.TextFontSize}pt;padding-bottom:.25em;" ] [
|
||||
li [ _style $"list-style-type:{bullet};padding-bottom:.25em;" ] [
|
||||
match req.Requestor with
|
||||
| Some r when r <> "" ->
|
||||
strong [] [ str r ]
|
||||
@ -825,7 +829,7 @@ with
|
||||
rawText " ("; str s["as of"].Value; str " "; str dt; rawText ")"
|
||||
]
|
||||
])
|
||||
|> ul []
|
||||
|> ul [ _style $"font-family:{p.FontStack};font-size:%i{p.TextFontSize}pt" ]
|
||||
br []
|
||||
]
|
||||
|> RenderView.AsString.htmlNodes
|
||||
|
@ -24,7 +24,7 @@ let delete chId : HttpHandler = requireAccess [ Admin ] >=> validateCsrf >=> fun
|
||||
let! _, stats = findStats churchId conn
|
||||
do! Churches.deleteById churchId conn
|
||||
addInfo ctx
|
||||
ctx.Strings["The church {0} and its {1} small groups (with {2} prayer request(s)) were deleted successfully; revoked access from {3} user(s)",
|
||||
ctx.Strings["The church “{0}” and its {1} small group(s) (with {2} prayer request(s)) were deleted successfully; revoked access from {3} user(s)",
|
||||
church.Name, stats.SmallGroups, stats.PrayerRequests, stats.Users]
|
||||
return! redirectTo false "/churches" next ctx
|
||||
| None -> return! fourOhFour ctx
|
||||
|
@ -2,7 +2,6 @@
|
||||
module PrayerTracker.Extensions
|
||||
|
||||
open Microsoft.AspNetCore.Http
|
||||
open Microsoft.FSharpLu
|
||||
open Newtonsoft.Json
|
||||
open NodaTime
|
||||
open NodaTime.Serialization.JsonNet
|
||||
@ -17,18 +16,18 @@ let private jsonSettings = JsonSerializerSettings().ConfigureForNodaTime DateTim
|
||||
type ISession with
|
||||
|
||||
/// Set an object in the session
|
||||
member this.SetObject key value =
|
||||
member this.SetObject<'T> key (value : 'T) =
|
||||
this.SetString (key, JsonConvert.SerializeObject (value, jsonSettings))
|
||||
|
||||
/// Get an object from the session
|
||||
member this.GetObject<'T> key =
|
||||
member this.TryGetObject<'T> key =
|
||||
match this.GetString key with
|
||||
| null -> Unchecked.defaultof<'T>
|
||||
| v -> JsonConvert.DeserializeObject<'T> (v, jsonSettings)
|
||||
| null -> None
|
||||
| v -> Some (JsonConvert.DeserializeObject<'T> (v, jsonSettings))
|
||||
|
||||
/// The currently logged on small group
|
||||
member this.CurrentGroup
|
||||
with get () = this.GetObject<SmallGroup> Key.Session.currentGroup |> Option.fromObject
|
||||
with get () = this.TryGetObject<SmallGroup> Key.Session.currentGroup
|
||||
and set (v : SmallGroup option) =
|
||||
match v with
|
||||
| Some group -> this.SetObject Key.Session.currentGroup group
|
||||
@ -36,7 +35,7 @@ type ISession with
|
||||
|
||||
/// The currently logged on user
|
||||
member this.CurrentUser
|
||||
with get () = this.GetObject<User> Key.Session.currentUser |> Option.fromObject
|
||||
with get () = this.TryGetObject<User> Key.Session.currentUser
|
||||
and set (v : User option) =
|
||||
match v with
|
||||
| Some user -> this.SetObject Key.Session.currentUser { user with PasswordHash = "" }
|
||||
@ -45,9 +44,8 @@ type ISession with
|
||||
/// Current messages for the session
|
||||
member this.Messages
|
||||
with get () =
|
||||
match box (this.GetObject<UserMessage list> Key.Session.userMessages) with
|
||||
| null -> List.empty<UserMessage>
|
||||
| msgs -> unbox msgs
|
||||
this.TryGetObject<UserMessage list> Key.Session.userMessages
|
||||
|> Option.defaultValue List.empty<UserMessage>
|
||||
and set (v : UserMessage list) = this.SetObject Key.Session.userMessages v
|
||||
|
||||
|
||||
@ -69,28 +67,18 @@ type ClaimsPrincipal with
|
||||
else None
|
||||
|
||||
|
||||
open System.Threading.Tasks
|
||||
open Giraffe
|
||||
open Microsoft.Extensions.Configuration
|
||||
open Npgsql
|
||||
|
||||
/// Extensions on the ASP.NET Core HTTP context
|
||||
type HttpContext with
|
||||
|
||||
// TODO: is this disposed?
|
||||
member private this.LazyConn : Lazy<Task<NpgsqlConnection>> = lazy (backgroundTask {
|
||||
let cfg = this.GetService<IConfiguration> ()
|
||||
let conn = new NpgsqlConnection (cfg.GetConnectionString "PrayerTracker")
|
||||
do! conn.OpenAsync ()
|
||||
return conn
|
||||
})
|
||||
/// The system clock (via DI)
|
||||
member this.Clock = this.GetService<IClock> ()
|
||||
|
||||
/// The PostgreSQL connection (configured via DI)
|
||||
member this.Conn = this.GetService<NpgsqlConnection> ()
|
||||
|
||||
/// The system clock (via DI)
|
||||
member this.Clock = this.GetService<IClock> ()
|
||||
|
||||
/// The current instant
|
||||
member this.Now = this.Clock.GetCurrentInstant ()
|
||||
|
||||
|
@ -23,7 +23,7 @@ let delete grpId : HttpHandler = requireAccess [ Admin ] >=> validateCsrf >=> fu
|
||||
let! users = Users.countByGroup groupId conn
|
||||
do! SmallGroups.deleteById groupId conn
|
||||
addInfo ctx
|
||||
ctx.Strings["The group {0} and its {1} prayer request(s) were deleted successfully; revoked access from {2} user(s)",
|
||||
ctx.Strings["The group “{0}” and its {1} prayer request(s) were deleted successfully; revoked access from {2} user(s)",
|
||||
grp.Name, reqs, users]
|
||||
return! redirectTo false "/small-groups" next ctx
|
||||
| None -> return! fourOhFour ctx
|
||||
|
@ -257,7 +257,8 @@ footer a:hover {
|
||||
.pt-radio-group {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 2rem;
|
||||
gap: 1.5rem;
|
||||
align-items: baseline;
|
||||
}
|
||||
.pt-center-text {
|
||||
text-align: center;
|
||||
|
@ -243,6 +243,13 @@ this.PT = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable or disable the font list based on whether the native font stack is selected or not
|
||||
*/
|
||||
checkFonts() {
|
||||
document.getElementById("Fonts").disabled = document.getElementById("IsNative_Y").checked
|
||||
},
|
||||
|
||||
/**
|
||||
* Bind the event handlers
|
||||
*/
|
||||
@ -261,6 +268,12 @@ this.PT = {
|
||||
})
|
||||
PT.smallGroup.preferences.toggleType(name)
|
||||
})
|
||||
;["Y", "N"].map(name => {
|
||||
document.getElementById(`IsNative_${name}`).addEventListener("click", () => {
|
||||
PT.smallGroup.preferences.checkFonts()
|
||||
})
|
||||
})
|
||||
PT.smallGroup.preferences.checkFonts()
|
||||
},
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user