Version 3.4 #78
@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.30114.105
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MyPrayerJournal", "MyPrayerJournal\MyPrayerJournal.fsproj", "{6BD5A3C8-F859-42A0-ACD7-A5819385E828}"
|
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MyPrayerJournal", "MyPrayerJournal\MyPrayerJournal.fsproj", "{6BD5A3C8-F859-42A0-ACD7-A5819385E828}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "MyPrayerJournal.ToPostgres", "MyPrayerJournal.ToPostgres\MyPrayerJournal.ToPostgres.fsproj", "{3114B8F4-E388-4804-94D3-A2F4D42797C6}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -24,9 +22,5 @@ Global
|
|||||||
{72B57736-8721-4636-A309-49FA4222416E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{72B57736-8721-4636-A309-49FA4222416E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{72B57736-8721-4636-A309-49FA4222416E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{72B57736-8721-4636-A309-49FA4222416E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{72B57736-8721-4636-A309-49FA4222416E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{72B57736-8721-4636-A309-49FA4222416E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3114B8F4-E388-4804-94D3-A2F4D42797C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3114B8F4-E388-4804-94D3-A2F4D42797C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3114B8F4-E388-4804-94D3-A2F4D42797C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3114B8F4-E388-4804-94D3-A2F4D42797C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -80,9 +80,8 @@ module Request =
|
|||||||
open NodaTime
|
open NodaTime
|
||||||
|
|
||||||
/// Add a request
|
/// Add a request
|
||||||
let add req = backgroundTask {
|
let add req =
|
||||||
do! insert Table.Request (RequestId.toString req.Id) req
|
insert<Request> Table.Request req
|
||||||
}
|
|
||||||
|
|
||||||
/// Does a request exist for the given request ID and user ID?
|
/// Does a request exist for the given request ID and user ID?
|
||||||
let existsById (reqId : RequestId) (userId : UserId) =
|
let existsById (reqId : RequestId) (userId : UserId) =
|
||||||
@ -100,7 +99,7 @@ module Request =
|
|||||||
let dbId = RequestId.toString reqId
|
let dbId = RequestId.toString reqId
|
||||||
match! existsById reqId userId with
|
match! existsById reqId userId with
|
||||||
| true -> do! Update.partialById Table.Request dbId {| Recurrence = recurType |}
|
| true -> do! Update.partialById Table.Request dbId {| Recurrence = recurType |}
|
||||||
| false -> invalidOp "Request ID {dbId} not found"
|
| false -> invalidOp $"Request ID {dbId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the show-after time for a request
|
/// Update the show-after time for a request
|
||||||
@ -108,7 +107,7 @@ module Request =
|
|||||||
let dbId = RequestId.toString reqId
|
let dbId = RequestId.toString reqId
|
||||||
match! existsById reqId userId with
|
match! existsById reqId userId with
|
||||||
| true -> do! Update.partialById Table.Request dbId {| ShowAfter = showAfter |}
|
| true -> do! Update.partialById Table.Request dbId {| ShowAfter = showAfter |}
|
||||||
| false -> invalidOp "Request ID {dbId} not found"
|
| false -> invalidOp $"Request ID {dbId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the snoozed and show-after values for a request
|
/// Update the snoozed and show-after values for a request
|
||||||
@ -116,7 +115,7 @@ module Request =
|
|||||||
let dbId = RequestId.toString reqId
|
let dbId = RequestId.toString reqId
|
||||||
match! existsById reqId userId with
|
match! existsById reqId userId with
|
||||||
| true -> do! Update.partialById Table.Request dbId {| SnoozedUntil = until; ShowAfter = until |}
|
| true -> do! Update.partialById Table.Request dbId {| SnoozedUntil = until; ShowAfter = until |}
|
||||||
| false -> invalidOp "Request ID {dbId} not found"
|
| false -> invalidOp $"Request ID {dbId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -130,7 +129,7 @@ module History =
|
|||||||
match! Request.tryById reqId userId with
|
match! Request.tryById reqId userId with
|
||||||
| Some req ->
|
| Some req ->
|
||||||
do! Update.partialById Table.Request dbId
|
do! Update.partialById Table.Request dbId
|
||||||
{| History = (hist :: req.History) |> List.sortByDescending (fun it -> it.AsOf) |}
|
{| History = (hist :: req.History) |> List.sortByDescending (_.AsOf) |}
|
||||||
| None -> invalidOp $"Request ID {dbId} not found"
|
| None -> invalidOp $"Request ID {dbId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +151,7 @@ module Journal =
|
|||||||
|> Seq.ofList
|
|> Seq.ofList
|
||||||
|> Seq.map JournalRequest.ofRequestLite
|
|> Seq.map JournalRequest.ofRequestLite
|
||||||
|> Seq.filter (fun it -> it.LastStatus = Answered)
|
|> Seq.filter (fun it -> it.LastStatus = Answered)
|
||||||
|> Seq.sortByDescending (fun it -> it.AsOf)
|
|> Seq.sortByDescending (_.AsOf)
|
||||||
|> List.ofSeq
|
|> List.ofSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +168,7 @@ module Journal =
|
|||||||
|> Seq.ofList
|
|> Seq.ofList
|
||||||
|> Seq.map JournalRequest.ofRequestLite
|
|> Seq.map JournalRequest.ofRequestLite
|
||||||
|> Seq.filter (fun it -> it.LastStatus <> Answered)
|
|> Seq.filter (fun it -> it.LastStatus <> Answered)
|
||||||
|> Seq.sortBy (fun it -> it.AsOf)
|
|> Seq.sortBy (_.AsOf)
|
||||||
|> List.ofSeq
|
|> List.ofSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +194,7 @@ module Note =
|
|||||||
match! Request.tryById reqId userId with
|
match! Request.tryById reqId userId with
|
||||||
| Some req ->
|
| Some req ->
|
||||||
do! Update.partialById Table.Request dbId
|
do! Update.partialById Table.Request dbId
|
||||||
{| Notes = (note :: req.Notes) |> List.sortByDescending (fun it -> it.AsOf) |}
|
{| Notes = (note :: req.Notes) |> List.sortByDescending (_.AsOf) |}
|
||||||
| None -> invalidOp $"Request ID {dbId} not found"
|
| None -> invalidOp $"Request ID {dbId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,14 +244,14 @@ module JournalRequest =
|
|||||||
// them at the bottom of the list.
|
// them at the bottom of the list.
|
||||||
// - Snoozed requests will reappear at the bottom of the list when they return.
|
// - Snoozed requests will reappear at the bottom of the list when they return.
|
||||||
// - New requests will go to the bottom of the list, but will rise as others are marked as prayed.
|
// - New requests will go to the bottom of the list, but will rise as others are marked as prayed.
|
||||||
let lastActivity = lastHistory |> Option.map (fun it -> it.AsOf) |> Option.defaultValue Instant.MinValue
|
let lastActivity = lastHistory |> Option.map (_.AsOf) |> Option.defaultValue Instant.MinValue
|
||||||
let showAfter = defaultArg req.ShowAfter Instant.MinValue
|
let showAfter = defaultArg req.ShowAfter Instant.MinValue
|
||||||
let snoozedUntil = defaultArg req.SnoozedUntil Instant.MinValue
|
let snoozedUntil = defaultArg req.SnoozedUntil Instant.MinValue
|
||||||
let lastPrayed =
|
let lastPrayed =
|
||||||
history
|
history
|
||||||
|> Seq.filter History.isPrayed
|
|> Seq.filter History.isPrayed
|
||||||
|> Seq.tryHead
|
|> Seq.tryHead
|
||||||
|> Option.map (fun it -> it.AsOf)
|
|> Option.map (_.AsOf)
|
||||||
|> Option.defaultValue Instant.MinValue
|
|> Option.defaultValue Instant.MinValue
|
||||||
let asOf = List.max [ lastPrayed; showAfter; snoozedUntil ]
|
let asOf = List.max [ lastPrayed; showAfter; snoozedUntil ]
|
||||||
{ RequestId = req.Id
|
{ RequestId = req.Id
|
||||||
|
@ -57,7 +57,7 @@ type HttpContext with
|
|||||||
|> Option.ofObj
|
|> Option.ofObj
|
||||||
|> Option.map (fun user -> user.Claims |> Seq.tryFind (fun u -> u.Type = ClaimTypes.NameIdentifier))
|
|> Option.map (fun user -> user.Claims |> Seq.tryFind (fun u -> u.Type = ClaimTypes.NameIdentifier))
|
||||||
|> Option.flatten
|
|> Option.flatten
|
||||||
|> Option.map (fun claim -> claim.Value)
|
|> Option.map (_.Value)
|
||||||
|
|
||||||
/// The current user's ID
|
/// The current user's ID
|
||||||
// NOTE: this may raise if you don't run the request through the requireUser handler first
|
// NOTE: this may raise if you don't run the request through the requireUser handler first
|
||||||
@ -294,7 +294,7 @@ module Journal =
|
|||||||
let usr =
|
let usr =
|
||||||
ctx.User.Claims
|
ctx.User.Claims
|
||||||
|> Seq.tryFind (fun c -> c.Type = ClaimTypes.GivenName)
|
|> Seq.tryFind (fun c -> c.Type = ClaimTypes.GivenName)
|
||||||
|> Option.map (fun c -> c.Value)
|
|> Option.map (_.Value)
|
||||||
|> Option.defaultValue "Your"
|
|> Option.defaultValue "Your"
|
||||||
let title = usr |> match usr with "Your" -> sprintf "%s" | _ -> sprintf "%s's"
|
let title = usr |> match usr with "Your" -> sprintf "%s" | _ -> sprintf "%s's"
|
||||||
return! partial $"{title} Prayer Journal" (Views.Journal.journal usr) next ctx
|
return! partial $"{title} Prayer Journal" (Views.Journal.journal usr) next ctx
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Version>3.3</Version>
|
<Version>3.4</Version>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
||||||
<PublishSingleFile>false</PublishSingleFile>
|
<PublishSingleFile>false</PublishSingleFile>
|
||||||
@ -20,16 +20,15 @@
|
|||||||
<Compile Include="Program.fs" />
|
<Compile Include="Program.fs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BitBadger.Npgsql.FSharp.Documents" Version="1.0.0-beta3" />
|
<PackageReference Include="BitBadger.Npgsql.FSharp.Documents" Version="2.0.0" />
|
||||||
<PackageReference Include="FSharp.SystemTextJson" Version="1.2.42" />
|
<PackageReference Include="FSharp.SystemTextJson" Version="1.2.42" />
|
||||||
<PackageReference Include="FunctionalCuid" Version="1.0.0" />
|
<PackageReference Include="FunctionalCuid" Version="1.0.0" />
|
||||||
<PackageReference Include="Giraffe" Version="6.2.0" />
|
<PackageReference Include="Giraffe" Version="6.2.0" />
|
||||||
<PackageReference Include="Giraffe.Htmx" Version="1.9.6" />
|
<PackageReference Include="Giraffe.Htmx" Version="1.9.8" />
|
||||||
<PackageReference Include="Giraffe.ViewEngine.Htmx" Version="1.9.6" />
|
<PackageReference Include="Giraffe.ViewEngine.Htmx" Version="1.9.8" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.11" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.0" />
|
||||||
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.1.2" />
|
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.1.2" />
|
||||||
<PackageReference Include="Npgsql.NodaTime" Version="7.0.6" />
|
<PackageReference Include="Npgsql.NodaTime" Version="8.0.1" />
|
||||||
<PackageReference Update="FSharp.Core" Version="7.0.400" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="wwwroot\" />
|
<Folder Include="wwwroot\" />
|
||||||
|
@ -80,7 +80,7 @@ let full (clock : IClock) tz (req : Request) =
|
|||||||
|> Seq.ofList
|
|> Seq.ofList
|
||||||
|> Seq.filter History.isAnswered
|
|> Seq.filter History.isAnswered
|
||||||
|> Seq.tryHead
|
|> Seq.tryHead
|
||||||
|> Option.map (fun x -> x.AsOf)
|
|> Option.map (_.AsOf)
|
||||||
let prayed = (req.History |> List.filter History.isPrayed |> List.length).ToString "N0"
|
let prayed = (req.History |> List.filter History.isPrayed |> List.length).ToString "N0"
|
||||||
let daysOpen =
|
let daysOpen =
|
||||||
let asOf = defaultArg answered now
|
let asOf = defaultArg answered now
|
||||||
@ -89,7 +89,7 @@ let full (clock : IClock) tz (req : Request) =
|
|||||||
req.History
|
req.History
|
||||||
|> Seq.ofList
|
|> Seq.ofList
|
||||||
|> Seq.filter (fun h -> Option.isSome h.Text)
|
|> Seq.filter (fun h -> Option.isSome h.Text)
|
||||||
|> Seq.sortByDescending (fun h -> h.AsOf)
|
|> Seq.sortByDescending (_.AsOf)
|
||||||
|> Seq.map (fun h -> Option.get h.Text)
|
|> Seq.map (fun h -> Option.get h.Text)
|
||||||
|> Seq.head
|
|> Seq.head
|
||||||
// The history log including notes (and excluding the final entry for answered requests)
|
// The history log including notes (and excluding the final entry for answered requests)
|
||||||
@ -100,7 +100,7 @@ let full (clock : IClock) tz (req : Request) =
|
|||||||
|> Seq.ofList
|
|> Seq.ofList
|
||||||
|> Seq.map (fun n -> {| asOf = n.AsOf; text = Some n.Notes; status = "Notes" |})
|
|> Seq.map (fun n -> {| asOf = n.AsOf; text = Some n.Notes; status = "Notes" |})
|
||||||
|> Seq.append (req.History |> List.map toDisp)
|
|> Seq.append (req.History |> List.map toDisp)
|
||||||
|> Seq.sortByDescending (fun it -> it.asOf)
|
|> Seq.sortByDescending (_.asOf)
|
||||||
|> List.ofSeq
|
|> List.ofSeq
|
||||||
// Skip the first entry for answered requests; that info is already displayed
|
// Skip the first entry for answered requests; that info is already displayed
|
||||||
match answered with Some _ -> all.Tail | None -> all
|
match answered with Some _ -> all.Tail | None -> all
|
||||||
|
Loading…
Reference in New Issue
Block a user