Version 8 #43
|
@ -952,7 +952,8 @@ module PrayerRequest =
|
|||
| Automatic, Expecting -> false
|
||||
| Automatic, _ ->
|
||||
// Automatic expiration
|
||||
asOf.PlusDays -group.Preferences.DaysToExpire > req.UpdatedDate.InZone(SmallGroup.timeZone group).Date
|
||||
Period.Between(req.UpdatedDate.InZone(SmallGroup.timeZone group).Date, asOf, PeriodUnits.Days).Days
|
||||
>= group.Preferences.DaysToExpire
|
||||
|
||||
/// Is an update required for this long-term request?
|
||||
let updateRequired asOf group req =
|
||||
|
|
|
@ -143,6 +143,8 @@ let memberTests =
|
|||
|
||||
[<Tests>]
|
||||
let prayerRequestTests =
|
||||
let instantNow = SystemClock.Instance.GetCurrentInstant
|
||||
let localDateNow () = (instantNow ()).InUtc().Date
|
||||
testList "PrayerRequest" [
|
||||
test "empty is as expected" {
|
||||
let mt = PrayerRequest.empty
|
||||
|
@ -150,8 +152,8 @@ let prayerRequestTests =
|
|||
Expect.equal mt.RequestType CurrentRequest "The request type should have been Current"
|
||||
Expect.equal mt.UserId.Value Guid.Empty "The user ID should have been an empty GUID"
|
||||
Expect.equal mt.SmallGroupId.Value Guid.Empty "The small group ID should have been an empty GUID"
|
||||
Expect.equal mt.EnteredDate DateTime.MinValue "The entered date should have been the minimum"
|
||||
Expect.equal mt.UpdatedDate DateTime.MinValue "The updated date should have been the minimum"
|
||||
Expect.equal mt.EnteredDate Instant.MinValue "The entered date should have been the minimum"
|
||||
Expect.equal mt.UpdatedDate Instant.MinValue "The updated date should have been the minimum"
|
||||
Expect.isNone mt.Requestor "The requestor should not exist"
|
||||
Expect.equal mt.Text "" "The request text should have been blank"
|
||||
Expect.isFalse mt.NotifyChaplain "The notify chaplain flag should not have been set"
|
||||
|
@ -159,62 +161,60 @@ let prayerRequestTests =
|
|||
Expect.equal mt.User.Id.Value Guid.Empty "The user should have been an empty one"
|
||||
Expect.equal mt.SmallGroup.Id.Value Guid.Empty "The small group should have been an empty one"
|
||||
}
|
||||
test "IsExpired always returns false for expecting requests" {
|
||||
let req = { PrayerRequest.empty with RequestType = Expecting }
|
||||
Expect.isFalse (req.IsExpired DateTime.Now 0) "An expecting request should never be considered expired"
|
||||
test "isExpired always returns false for expecting requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = Expecting }
|
||||
|> Flip.Expect.isFalse "An expecting request should never be considered expired"
|
||||
}
|
||||
test "IsExpired always returns false for manually-expired requests" {
|
||||
let req = { PrayerRequest.empty with UpdatedDate = DateTime.Now.AddMonths -1; Expiration = Manual }
|
||||
Expect.isFalse (req.IsExpired DateTime.Now 4) "A never-expired request should never be considered expired"
|
||||
test "isExpired always returns false for manually-expired requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = (instantNow ()) - Duration.FromDays 1; Expiration = Manual }
|
||||
|> Flip.Expect.isFalse "A never-expired request should never be considered expired"
|
||||
}
|
||||
test "IsExpired always returns false for long term/recurring requests" {
|
||||
let req = { PrayerRequest.empty with RequestType = LongTermRequest }
|
||||
Expect.isFalse (req.IsExpired DateTime.Now 0)
|
||||
"A recurring/long-term request should never be considered expired"
|
||||
test "isExpired always returns false for long term/recurring requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = LongTermRequest }
|
||||
|> Flip.Expect.isFalse "A recurring/long-term request should never be considered expired"
|
||||
}
|
||||
test "IsExpired always returns true for force-expired requests" {
|
||||
let req = { PrayerRequest.empty with UpdatedDate = DateTime.Now; Expiration = Forced }
|
||||
Expect.isTrue (req.IsExpired DateTime.Now 5) "A force-expired request should always be considered expired"
|
||||
test "isExpired always returns true for force-expired requests" {
|
||||
PrayerRequest.isExpired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = (instantNow ()); Expiration = Forced }
|
||||
|> Flip.Expect.isTrue "A force-expired request should always be considered expired"
|
||||
}
|
||||
test "IsExpired returns false for non-expired requests" {
|
||||
let now = DateTime.Now
|
||||
let req = { PrayerRequest.empty with UpdatedDate = now.AddDays -5. }
|
||||
Expect.isFalse (req.IsExpired now 7) "A request updated 5 days ago should not be considered expired"
|
||||
test "isExpired returns false for non-expired requests" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.isExpired (now.InUtc().Date) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = now - Duration.FromDays 5 }
|
||||
|> Flip.Expect.isFalse "A request updated 5 days ago should not be considered expired"
|
||||
}
|
||||
test "IsExpired returns true for expired requests" {
|
||||
let now = DateTime.Now
|
||||
let req = { PrayerRequest.empty with UpdatedDate = now.AddDays -8. }
|
||||
Expect.isTrue (req.IsExpired now 7) "A request updated 8 days ago should be considered expired"
|
||||
test "isExpired returns true for expired requests" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.isExpired (now.InUtc().Date) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = now - Duration.FromDays 15 }
|
||||
|> Flip.Expect.isTrue "A request updated 15 days ago should be considered expired"
|
||||
}
|
||||
test "IsExpired returns true for same-day expired requests" {
|
||||
let now = DateTime.Now
|
||||
let req = { PrayerRequest.empty with UpdatedDate = now.Date.AddDays(-7.).AddSeconds -1. }
|
||||
Expect.isTrue (req.IsExpired now 7)
|
||||
"A request entered a second before midnight should be considered expired"
|
||||
test "isExpired returns true for same-day expired requests" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.isExpired (now.InUtc().Date) SmallGroup.empty
|
||||
{ PrayerRequest.empty with UpdatedDate = now - (Duration.FromDays 14) - (Duration.FromSeconds 1L) }
|
||||
|> Flip.Expect.isTrue "A request entered a second before midnight should be considered expired"
|
||||
}
|
||||
test "UpdateRequired returns false for expired requests" {
|
||||
let req = { PrayerRequest.empty with Expiration = Forced }
|
||||
Expect.isFalse (req.UpdateRequired DateTime.Now 7 4) "An expired request should not require an update"
|
||||
test "updateRequired returns false for expired requests" {
|
||||
PrayerRequest.updateRequired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with Expiration = Forced }
|
||||
|> Flip.Expect.isFalse "An expired request should not require an update"
|
||||
}
|
||||
test "UpdateRequired returns false when an update is not required for an active request" {
|
||||
let now = DateTime.Now
|
||||
let req =
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = LongTermRequest
|
||||
UpdatedDate = now.AddDays -14.
|
||||
}
|
||||
Expect.isFalse (req.UpdateRequired now 7 4)
|
||||
"An active request updated 14 days ago should not require an update until 28 days"
|
||||
test "updateRequired returns false when an update is not required for an active request" {
|
||||
let now = instantNow ()
|
||||
PrayerRequest.updateRequired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = LongTermRequest; UpdatedDate = now - Duration.FromDays 14 }
|
||||
|> Flip.Expect.isFalse "An active request updated 14 days ago should not require an update until 28 days"
|
||||
}
|
||||
test "UpdateRequired returns true when an update is required for an active request" {
|
||||
let now = DateTime.Now
|
||||
let req =
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = LongTermRequest
|
||||
UpdatedDate = now.AddDays -34.
|
||||
}
|
||||
Expect.isTrue (req.UpdateRequired now 7 4)
|
||||
"An active request updated 34 days ago should require an update (past 28 days)"
|
||||
let now = instantNow ()
|
||||
PrayerRequest.updateRequired (localDateNow ()) SmallGroup.empty
|
||||
{ PrayerRequest.empty with RequestType = LongTermRequest; UpdatedDate = now - Duration.FromDays 34 }
|
||||
|> Flip.Expect.isTrue "An active request updated 34 days ago should require an update (past 28 days)"
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -288,9 +288,9 @@ let requestSortTests =
|
|||
[<Tests>]
|
||||
let smallGroupTests =
|
||||
testList "SmallGroup" [
|
||||
let now = DateTime (2017, 5, 12, 12, 15, 0, DateTimeKind.Utc)
|
||||
let now = Instant.FromDateTimeUtc (DateTime (2017, 5, 12, 12, 15, 0, DateTimeKind.Utc))
|
||||
let withFakeClock f () =
|
||||
FakeClock (Instant.FromDateTimeUtc now) |> f
|
||||
FakeClock now |> f
|
||||
yield test "empty is as expected" {
|
||||
let mt = SmallGroup.empty
|
||||
Expect.equal mt.Id.Value Guid.Empty "The small group ID should have been an empty GUID"
|
||||
|
@ -311,10 +311,12 @@ let smallGroupTests =
|
|||
{ SmallGroup.empty with
|
||||
Preferences = { ListPreferences.empty with TimeZoneId = TimeZoneId "Europe/Berlin" }
|
||||
}
|
||||
Expect.isGreaterThan (grp.LocalTimeNow clock) now "UTC to Europe/Berlin should have added hours"
|
||||
let tz = DateTimeZoneProviders.Tzdb["Europe/Berlin"]
|
||||
Expect.isGreaterThan (SmallGroup.localTimeNow clock grp) (now.InUtc().LocalDateTime)
|
||||
"UTC to Europe/Berlin should have added hours"
|
||||
"LocalTimeNow adjusts the time behind UTC",
|
||||
fun clock ->
|
||||
Expect.isLessThan (SmallGroup.empty.LocalTimeNow clock) now
|
||||
Expect.isLessThan (SmallGroup.localTimeNow clock SmallGroup.empty) (now.InUtc().LocalDateTime)
|
||||
"UTC to America/Denver should have subtracted hours"
|
||||
"LocalTimeNow returns UTC when the time zone is invalid",
|
||||
fun clock ->
|
||||
|
@ -322,16 +324,17 @@ let smallGroupTests =
|
|||
{ SmallGroup.empty with
|
||||
Preferences = { ListPreferences.empty with TimeZoneId = TimeZoneId "garbage" }
|
||||
}
|
||||
Expect.equal (grp.LocalTimeNow clock) now "UTC should have been returned for an invalid time zone"
|
||||
Expect.equal (SmallGroup.localTimeNow clock grp) (now.InUtc().LocalDateTime)
|
||||
"UTC should have been returned for an invalid time zone"
|
||||
]
|
||||
yield test "LocalTimeNow fails when clock is not passed" {
|
||||
Expect.throws (fun () -> (SmallGroup.empty.LocalTimeNow >> ignore) null)
|
||||
yield test "localTimeNow fails when clock is not passed" {
|
||||
Expect.throws (fun () -> (SmallGroup.localTimeNow null SmallGroup.empty |> ignore))
|
||||
"Should have raised an exception for null clock"
|
||||
}
|
||||
yield test "LocalDateNow returns the date portion" {
|
||||
let now' = DateTime (2017, 5, 12, 1, 15, 0, DateTimeKind.Utc)
|
||||
let clock = FakeClock (Instant.FromDateTimeUtc now')
|
||||
Expect.isLessThan (SmallGroup.empty.LocalDateNow clock) now.Date "The date should have been a day earlier"
|
||||
let clock = FakeClock (Instant.FromDateTimeUtc (DateTime (2017, 5, 12, 1, 15, 0, DateTimeKind.Utc)))
|
||||
Expect.isLessThan (SmallGroup.localDateNow clock SmallGroup.empty) (now.InUtc().Date)
|
||||
"The date should have been a day earlier"
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
open System
|
||||
open Expecto
|
||||
open Microsoft.AspNetCore.Html
|
||||
open NodaTime
|
||||
open PrayerTracker.Entities
|
||||
open PrayerTracker.Tests.TestLocalization
|
||||
open PrayerTracker.Utils
|
||||
|
@ -121,7 +122,7 @@ let appViewInfoTests =
|
|||
Expect.isNone vi.HelpLink "The help link should have been set to none"
|
||||
Expect.isEmpty vi.Messages "There should have been no messages set"
|
||||
Expect.equal vi.Version "" "The version should have been blank"
|
||||
Expect.isGreaterThan vi.RequestStart DateTime.MinValue.Ticks "The request start time should have been set"
|
||||
Expect.equal vi.RequestStart Instant.MinValue "The request start time should have been the minimum value"
|
||||
Expect.isNone vi.User "There should not have been a user"
|
||||
Expect.isNone vi.Group "There should not have been a small group"
|
||||
}
|
||||
|
@ -497,30 +498,31 @@ let messageLevelTests =
|
|||
let requestListTests =
|
||||
testList "RequestList" [
|
||||
let withRequestList f () =
|
||||
{ Requests = [
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = CurrentRequest
|
||||
Requestor = Some "Zeb"
|
||||
Text = "zyx"
|
||||
UpdatedDate = DateTime.Today
|
||||
}
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = CurrentRequest
|
||||
Requestor = Some "Aaron"
|
||||
Text = "abc"
|
||||
UpdatedDate = DateTime.Today - TimeSpan.FromDays 9.
|
||||
}
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = PraiseReport
|
||||
Text = "nmo"
|
||||
UpdatedDate = DateTime.Today
|
||||
}
|
||||
]
|
||||
Date = DateTime.Today
|
||||
SmallGroup = SmallGroup.empty
|
||||
ShowHeader = false
|
||||
Recipients = []
|
||||
CanEmail = false
|
||||
let today = SystemClock.Instance.GetCurrentInstant ()
|
||||
{ Requests = [
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = CurrentRequest
|
||||
Requestor = Some "Zeb"
|
||||
Text = "zyx"
|
||||
UpdatedDate = today
|
||||
}
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = CurrentRequest
|
||||
Requestor = Some "Aaron"
|
||||
Text = "abc"
|
||||
UpdatedDate = today - Duration.FromDays 9
|
||||
}
|
||||
{ PrayerRequest.empty with
|
||||
RequestType = PraiseReport
|
||||
Text = "nmo"
|
||||
UpdatedDate = today
|
||||
}
|
||||
]
|
||||
Date = today.InUtc().Date
|
||||
SmallGroup = SmallGroup.empty
|
||||
ShowHeader = false
|
||||
Recipients = []
|
||||
CanEmail = false
|
||||
}
|
||||
|> f
|
||||
yield! testFixture withRequestList [
|
||||
|
@ -574,7 +576,7 @@ let requestListTests =
|
|||
[ """<div style="text-align:center;font-family:Century Gothic,Tahoma,Luxi Sans,sans-serif">"""
|
||||
"""<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"
|
||||
htmlList.Date.ToString ("MMMM d, yyyy", null)
|
||||
"</span></div><br>"
|
||||
]
|
||||
|> String.concat ""
|
||||
|
@ -592,7 +594,7 @@ let requestListTests =
|
|||
}
|
||||
let html = htmlList.AsHtml _s
|
||||
let expected =
|
||||
htmlList.Requests[0].UpdatedDate.ToShortDateString ()
|
||||
htmlList.Requests[0].UpdatedDate.InUtc().Date.ToString ("d", null)
|
||||
|> sprintf """<strong>Zeb</strong> — zyx<i style="font-size:9.60pt"> (as of %s)</i>"""
|
||||
// spot check; if one request has it, they all should
|
||||
Expect.stringContains html expected "Expected short as-of date not found"
|
||||
|
@ -607,7 +609,7 @@ let requestListTests =
|
|||
}
|
||||
let html = htmlList.AsHtml _s
|
||||
let expected =
|
||||
htmlList.Requests[0].UpdatedDate.ToLongDateString ()
|
||||
htmlList.Requests[0].UpdatedDate.InUtc().Date.ToString ("D", null)
|
||||
|> sprintf """<strong>Zeb</strong> — zyx<i style="font-size:9.60pt"> (as of %s)</i>"""
|
||||
// spot check; if one request has it, they all should
|
||||
Expect.stringContains html expected "Expected long as-of date not found"
|
||||
|
@ -617,7 +619,8 @@ let requestListTests =
|
|||
let text = textList.AsText _s
|
||||
Expect.stringContains text $"{textList.SmallGroup.Name}\n" "Small group name not found"
|
||||
Expect.stringContains text "Prayer Requests\n" "List heading not found"
|
||||
Expect.stringContains text ((textList.Date.ToString "MMMM d, yyyy") + "\n \n") "List date not found"
|
||||
Expect.stringContains text ((textList.Date.ToString ("MMMM d, yyyy", null)) + "\n \n")
|
||||
"List date not found"
|
||||
Expect.stringContains text "--------------------\n CURRENT REQUESTS\n--------------------\n"
|
||||
"""Heading for category "Current Requests" not found"""
|
||||
Expect.stringContains text " + Zeb - zyx\n" "First request not found"
|
||||
|
@ -637,7 +640,7 @@ let requestListTests =
|
|||
}
|
||||
let text = textList.AsText _s
|
||||
let expected =
|
||||
textList.Requests[0].UpdatedDate.ToShortDateString ()
|
||||
textList.Requests[0].UpdatedDate.InUtc().Date.ToString ("d", null)
|
||||
|> sprintf " + Zeb - zyx (as of %s)"
|
||||
// spot check; if one request has it, they all should
|
||||
Expect.stringContains text expected "Expected short as-of date not found"
|
||||
|
@ -652,7 +655,7 @@ let requestListTests =
|
|||
}
|
||||
let text = textList.AsText _s
|
||||
let expected =
|
||||
textList.Requests[0].UpdatedDate.ToLongDateString ()
|
||||
textList.Requests[0].UpdatedDate.InUtc().Date.ToString ("D", null)
|
||||
|> sprintf " + Zeb - zyx (as of %s)"
|
||||
// spot check; if one request has it, they all should
|
||||
Expect.stringContains text expected "Expected long as-of date not found"
|
||||
|
|
|
@ -38,15 +38,13 @@ let edit (model : EditRequest) today ctx viewInfo =
|
|||
inputField "date" (nameof model.EnteredDate) "" [ _placeholder today ]
|
||||
]
|
||||
else
|
||||
// TODO: do these need to be nested like this?
|
||||
div [ _inputField ] [
|
||||
br []
|
||||
div [ _checkboxField ] [
|
||||
br []
|
||||
inputField "checkbox" (nameof model.SkipDateUpdate) "True" []
|
||||
label [ _for (nameof model.SkipDateUpdate) ] [ locStr s["Check to not update the date"] ]
|
||||
br []
|
||||
small [] [ em [] [ str (s["Typo Corrections"].Value.ToLower ()); rawText ", etc." ] ]
|
||||
]
|
||||
small [] [ em [] [ str (s["Typo Corrections"].Value.ToLower ()); rawText ", etc." ] ]
|
||||
]
|
||||
]
|
||||
div [ _fieldRow ] [
|
||||
|
@ -57,7 +55,7 @@ let edit (model : EditRequest) today ctx viewInfo =
|
|||
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 ] [ locStr (snd exp) ]
|
||||
label [ _for radioId ] [ space; locStr (snd exp) ]
|
||||
rawText " "
|
||||
])
|
||||
|> div [ _class "pt-center-text" ]
|
||||
|
|
|
@ -768,7 +768,7 @@ with
|
|||
/// Is this request new?
|
||||
member this.IsNew (req : PrayerRequest) =
|
||||
let reqDate = req.UpdatedDate.InZone(SmallGroup.timeZone this.SmallGroup).Date
|
||||
Period.Between(this.Date, reqDate, PeriodUnits.Days).Days <= this.SmallGroup.Preferences.DaysToKeepNew
|
||||
Period.Between(reqDate, this.Date, PeriodUnits.Days).Days <= this.SmallGroup.Preferences.DaysToKeepNew
|
||||
|
||||
/// Generate this list as HTML
|
||||
member this.AsHtml (s : IStringLocalizer) =
|
||||
|
@ -797,6 +797,7 @@ with
|
|||
]
|
||||
]
|
||||
]
|
||||
let tz = SmallGroup.timeZone this.SmallGroup
|
||||
reqs
|
||||
|> List.map (fun req ->
|
||||
let bullet = if this.IsNew req then "circle" else "disc"
|
||||
|
@ -804,7 +805,7 @@ with
|
|||
match req.Requestor with
|
||||
| Some r when r <> "" ->
|
||||
strong [] [ str r ]
|
||||
rawText " — "
|
||||
rawText " – "
|
||||
| Some _ -> ()
|
||||
| None -> ()
|
||||
rawText req.Text
|
||||
|
@ -814,8 +815,8 @@ with
|
|||
| LongDate ->
|
||||
let dt =
|
||||
match p.AsOfDateDisplay with
|
||||
| ShortDate -> req.UpdatedDate.ToString ("d", null)
|
||||
| LongDate -> req.UpdatedDate.ToString ("D", null)
|
||||
| ShortDate -> req.UpdatedDate.InZone(tz).Date.ToString ("d", null)
|
||||
| LongDate -> req.UpdatedDate.InZone(tz).Date.ToString ("D", null)
|
||||
| _ -> ""
|
||||
i [ _style $"font-size:%.2f{asOfSize}pt" ] [
|
||||
rawText " ("; str s["as of"].Value; str " "; str dt; rawText ")"
|
||||
|
@ -828,6 +829,7 @@ with
|
|||
|
||||
/// Generate this list as plain text
|
||||
member this.AsText (s : IStringLocalizer) =
|
||||
let tz = SmallGroup.timeZone this.SmallGroup
|
||||
seq {
|
||||
this.SmallGroup.Name
|
||||
s["Prayer Requests"].Value
|
||||
|
@ -846,8 +848,8 @@ with
|
|||
| _ ->
|
||||
let dt =
|
||||
match this.SmallGroup.Preferences.AsOfDateDisplay with
|
||||
| ShortDate -> req.UpdatedDate.ToString ("d", null)
|
||||
| LongDate -> req.UpdatedDate.ToString ("D", null)
|
||||
| ShortDate -> req.UpdatedDate.InZone(tz).Date.ToString ("d", null)
|
||||
| LongDate -> req.UpdatedDate.InZone(tz).Date.ToString ("D", null)
|
||||
| _ -> ""
|
||||
$""" ({s["as of"].Value} {dt})"""
|
||||
|> sprintf " %s %s%s%s" bullet requestor (htmlToPlainText req.Text)
|
||||
|
|
|
@ -4,19 +4,26 @@ module PrayerTracker.Extensions
|
|||
open Microsoft.AspNetCore.Http
|
||||
open Microsoft.FSharpLu
|
||||
open Newtonsoft.Json
|
||||
open NodaTime
|
||||
open NodaTime.Serialization.JsonNet
|
||||
open PrayerTracker.Entities
|
||||
open PrayerTracker.ViewModels
|
||||
|
||||
/// JSON.NET serializer settings for NodaTime
|
||||
let private jsonSettings = JsonSerializerSettings().ConfigureForNodaTime DateTimeZoneProviders.Tzdb
|
||||
|
||||
/// Extensions on the .NET session object
|
||||
type ISession with
|
||||
|
||||
/// Set an object in the session
|
||||
member this.SetObject key value =
|
||||
this.SetString (key, JsonConvert.SerializeObject value)
|
||||
this.SetString (key, JsonConvert.SerializeObject (value, jsonSettings))
|
||||
|
||||
/// Get an object from the session
|
||||
member this.GetObject<'T> key =
|
||||
match this.GetString key with null -> Unchecked.defaultof<'T> | v -> JsonConvert.DeserializeObject<'T> v
|
||||
match this.GetString key with
|
||||
| null -> Unchecked.defaultof<'T>
|
||||
| v -> JsonConvert.DeserializeObject<'T> (v, jsonSettings)
|
||||
|
||||
/// The currently logged on small group
|
||||
member this.CurrentGroup
|
||||
|
@ -63,7 +70,6 @@ type ClaimsPrincipal with
|
|||
|
||||
|
||||
open Giraffe
|
||||
open NodaTime
|
||||
open PrayerTracker
|
||||
|
||||
/// Extensions on the ASP.NET Core HTTP context
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<PackageReference Include="Giraffe" Version="6.0.0" />
|
||||
<PackageReference Include="Giraffe.Htmx" Version="1.8.0" />
|
||||
<PackageReference Include="NeoSmart.Caching.Sqlite" Version="6.0.1" />
|
||||
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.0.0" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.6" />
|
||||
<PackageReference Update="FSharp.Core" Version="6.0.5" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="6.0.6" />
|
||||
|
|
|
@ -238,6 +238,7 @@ footer a:hover {
|
|||
flex-flow: row wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
}
|
||||
.pt-field {
|
||||
display: flex;
|
||||
|
@ -255,9 +256,6 @@ footer a:hover {
|
|||
text-transform: uppercase;
|
||||
color: #777;
|
||||
}
|
||||
.pt-field ~ .pt-field {
|
||||
margin-left: 3rem;
|
||||
}
|
||||
.pt-center-text {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user