Search, Paging, and "As of" Date #10
|
@ -14,11 +14,11 @@ module private Helpers =
|
|||
/// Central place to append sort criteria for prayer request queries
|
||||
let reqSort sort (query : IQueryable<PrayerRequest>) =
|
||||
match sort with
|
||||
| "D" ->
|
||||
| SortByDate ->
|
||||
query.OrderByDescending(fun pr -> pr.updatedDate)
|
||||
.ThenByDescending(fun pr -> pr.enteredDate)
|
||||
.ThenBy(fun pr -> pr.requestor)
|
||||
| _ ->
|
||||
| SortByRequestor ->
|
||||
query.OrderBy(fun pr -> pr.requestor)
|
||||
.ThenByDescending(fun pr -> pr.updatedDate)
|
||||
.ThenByDescending(fun pr -> pr.enteredDate)
|
||||
|
|
|
@ -54,31 +54,65 @@ with
|
|||
| "L" -> LongDate
|
||||
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
|
||||
/// Convert this DU case to a single-character string
|
||||
member this.toCode () =
|
||||
member this.code =
|
||||
match this with
|
||||
| NoDisplay -> "N"
|
||||
| ShortDate -> "S"
|
||||
| LongDate -> "L"
|
||||
|
||||
|
||||
/// How requests should be sorted
|
||||
type RequestSort =
|
||||
/// Sort by date, then by requestor/subject
|
||||
| SortByDate
|
||||
/// Sort by requestor/subject, then by date
|
||||
| SortByRequestor
|
||||
with
|
||||
/// Convert to a DU case from a single-character string
|
||||
static member fromCode code =
|
||||
match code with
|
||||
| "D" -> SortByDate
|
||||
| "R" -> SortByRequestor
|
||||
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
|
||||
/// Convert this DU case to a single-character string
|
||||
member this.code =
|
||||
match this with
|
||||
| SortByDate -> "D"
|
||||
| SortByRequestor -> "R"
|
||||
|
||||
|
||||
module Converters =
|
||||
open Microsoft.EntityFrameworkCore.Storage.ValueConversion
|
||||
open Microsoft.FSharp.Linq.RuntimeHelpers
|
||||
open System.Linq.Expressions
|
||||
|
||||
let private fromDU =
|
||||
<@ Func<AsOfDateDisplay, string>(fun (x : AsOfDateDisplay) -> x.toCode ()) @>
|
||||
let private asOfFromDU =
|
||||
<@ Func<AsOfDateDisplay, string>(fun (x : AsOfDateDisplay) -> x.code) @>
|
||||
|> LeafExpressionConverter.QuotationToExpression
|
||||
|> unbox<Expression<Func<AsOfDateDisplay, string>>>
|
||||
|
||||
let private toDU =
|
||||
let private asOfToDU =
|
||||
<@ Func<string, AsOfDateDisplay>(AsOfDateDisplay.fromCode) @>
|
||||
|> LeafExpressionConverter.QuotationToExpression
|
||||
|> unbox<Expression<Func<string, AsOfDateDisplay>>>
|
||||
|
||||
let private sortFromDU =
|
||||
<@ Func<RequestSort, string>(fun (x : RequestSort) -> x.code) @>
|
||||
|> LeafExpressionConverter.QuotationToExpression
|
||||
|> unbox<Expression<Func<RequestSort, string>>>
|
||||
|
||||
let private sortToDU =
|
||||
<@ Func<string, RequestSort>(RequestSort.fromCode) @>
|
||||
|> LeafExpressionConverter.QuotationToExpression
|
||||
|> unbox<Expression<Func<string, RequestSort>>>
|
||||
|
||||
/// Conversion between a string and an AsOfDateDisplay DU value
|
||||
type AsOfDateDisplayConverter () =
|
||||
inherit ValueConverter<AsOfDateDisplay, string> (fromDU, toDU)
|
||||
inherit ValueConverter<AsOfDateDisplay, string> (asOfFromDU, asOfToDU)
|
||||
|
||||
/// Conversion between a string and a RequestSort DU value
|
||||
type RequestSortConverter () =
|
||||
inherit ValueConverter<RequestSort, string> (sortFromDU, sortToDU)
|
||||
|
||||
|
||||
/// Statistics for churches
|
||||
|
@ -189,7 +223,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
|
|||
/// The font size for the text on the prayer request list
|
||||
textFontSize : int
|
||||
/// The order in which the prayer requests are sorted
|
||||
requestSort : string
|
||||
requestSort : RequestSort
|
||||
/// The password used for "small group login" (view-only request list)
|
||||
groupPassword : string
|
||||
/// The default e-mail type for this class
|
||||
|
@ -219,7 +253,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
|
|||
lineColor = "navy"
|
||||
headingFontSize = 16
|
||||
textFontSize = 12
|
||||
requestSort = "D"
|
||||
requestSort = SortByDate
|
||||
groupPassword = ""
|
||||
defaultEmailType = EmailType.Html
|
||||
isPublic = false
|
||||
|
@ -289,7 +323,7 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
|
|||
.HasColumnName("RequestSort")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1)
|
||||
.HasDefaultValue "D"
|
||||
.HasDefaultValue SortByDate
|
||||
|> ignore
|
||||
m.Property(fun e -> e.groupPassword)
|
||||
.HasColumnName("GroupPassword")
|
||||
|
@ -323,6 +357,8 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
|
|||
.HasDefaultValue NoDisplay
|
||||
|> ignore)
|
||||
|> ignore
|
||||
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("requestSort")
|
||||
.SetValueConverter(Converters.RequestSortConverter ())
|
||||
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("asOfDateDisplay")
|
||||
.SetValueConverter(Converters.AsOfDateDisplayConverter ())
|
||||
|
||||
|
|
|
@ -5,6 +5,33 @@ open NodaTime.Testing
|
|||
open NodaTime
|
||||
open System
|
||||
|
||||
[<Tests>]
|
||||
let asOfDateDisplayTests =
|
||||
testList "AsOfDateDisplay" [
|
||||
test "NoDisplay code is correct" {
|
||||
Expect.equal NoDisplay.code "N" "The code for NoDisplay should have been \"N\""
|
||||
}
|
||||
test "ShortDate code is correct" {
|
||||
Expect.equal ShortDate.code "S" "The code for ShortDate should have been \"S\""
|
||||
}
|
||||
test "LongDate code is correct" {
|
||||
Expect.equal LongDate.code "L" "The code for LongDate should have been \"N\""
|
||||
}
|
||||
test "fromCode N should return NoDisplay" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "N") NoDisplay "\"N\" should have been converted to NoDisplay"
|
||||
}
|
||||
test "fromCode S should return ShortDate" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "S") ShortDate "\"S\" should have been converted to ShortDate"
|
||||
}
|
||||
test "fromCode L should return LongDate" {
|
||||
Expect.equal (AsOfDateDisplay.fromCode "L") LongDate "\"L\" should have been converted to LongDate"
|
||||
}
|
||||
test "fromCode X should raise" {
|
||||
Expect.throws (fun () -> AsOfDateDisplay.fromCode "X" |> ignore)
|
||||
"An unknown code should have raised an exception"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let churchTests =
|
||||
testList "Church" [
|
||||
|
@ -38,7 +65,7 @@ let listPreferencesTests =
|
|||
Expect.equal mt.lineColor "navy" "The default heding 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 "D" "The default request sort should have been D (date)"
|
||||
Expect.equal mt.requestSort SortByDate "The default request sort should have been by date"
|
||||
Expect.equal mt.groupPassword "" "The default group password should have been blank"
|
||||
Expect.equal mt.defaultEmailType EmailType.Html "The default e-mail type should have been HTML"
|
||||
Expect.isFalse mt.isPublic "The isPublic flag should not have been set"
|
||||
|
@ -130,6 +157,26 @@ let prayerRequestTests =
|
|||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let requestSortTests =
|
||||
testList "RequestSort" [
|
||||
test "SortByDate code is correct" {
|
||||
Expect.equal SortByDate.code "D" "The code for SortByDate should have been \"D\""
|
||||
}
|
||||
test "SortByRequestor code is correct" {
|
||||
Expect.equal SortByRequestor.code "R" "The code for SortByRequestor should have been \"R\""
|
||||
}
|
||||
test "fromCode D should return SortByDate" {
|
||||
Expect.equal (RequestSort.fromCode "D") SortByDate "\"D\" should have been converted to SortByDate"
|
||||
}
|
||||
test "fromCode R should return SortByRequestor" {
|
||||
Expect.equal (RequestSort.fromCode "R") SortByRequestor "\"R\" should have been converted to SortByRequestor"
|
||||
}
|
||||
test "fromCode Q should raise" {
|
||||
Expect.throws (fun () -> RequestSort.fromCode "Q" |> ignore) "An unknown code should have raised an exception"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let smallGroupTests =
|
||||
testList "SmallGroup" [
|
||||
|
|
|
@ -15,6 +15,18 @@ let countAll _ = true
|
|||
|
||||
module ReferenceListTests =
|
||||
|
||||
[<Tests>]
|
||||
let asOfDateListTests =
|
||||
testList "ReferenceList.asOfDateList" [
|
||||
test "has all three options listed" {
|
||||
let asOf = ReferenceList.asOfDateList _s
|
||||
Expect.hasCountOf asOf 3u countAll "There should have been 3 as-of choices returned"
|
||||
Expect.exists asOf (fun (x, _) -> x = NoDisplay.code) "The option for no display was not found"
|
||||
Expect.exists asOf (fun (x, _) -> x = ShortDate.code) "The option for a short date was not found"
|
||||
Expect.exists asOf (fun (x, _) -> x = LongDate.code) "The option for a full date was not found"
|
||||
}
|
||||
]
|
||||
|
||||
[<Tests>]
|
||||
let emailTypeListTests =
|
||||
testList "ReferenceList.emailTypeList" [
|
||||
|
@ -248,7 +260,7 @@ let editPreferencesTests =
|
|||
Expect.equal edit.expireDays prefs.daysToExpire "The expiration days were not filled correctly"
|
||||
Expect.equal edit.daysToKeepNew prefs.daysToKeepNew "The days to keep new were not filled correctly"
|
||||
Expect.equal edit.longTermUpdateWeeks prefs.longTermUpdateWeeks "The weeks for update were not filled correctly"
|
||||
Expect.equal edit.requestSort prefs.requestSort "The request sort was not filled correctly"
|
||||
Expect.equal edit.requestSort prefs.requestSort.code "The request sort was not filled correctly"
|
||||
Expect.equal edit.emailFromName prefs.emailFromName "The e-mail from name was not filled correctly"
|
||||
Expect.equal edit.emailFromAddress prefs.emailFromAddress "The e-mail from address was not filled correctly"
|
||||
Expect.equal edit.defaultEmailType prefs.defaultEmailType "The default e-mail type was not filled correctly"
|
||||
|
@ -572,7 +584,9 @@ let requestListTests =
|
|||
let newList =
|
||||
{ reqList with
|
||||
listGroup =
|
||||
{ reqList.listGroup with preferences = { reqList.listGroup.preferences with requestSort = "R" } }
|
||||
{ reqList.listGroup with
|
||||
preferences = { reqList.listGroup.preferences with requestSort = SortByRequestor }
|
||||
}
|
||||
}
|
||||
let reqs = newList.requestsInCategory RequestType.Current
|
||||
Expect.hasCountOf reqs 2u countAll "There should have been two requests"
|
||||
|
|
|
@ -12,9 +12,9 @@ module ReferenceList =
|
|||
|
||||
/// A localized list of the AsOfDateDisplay DU cases
|
||||
let asOfDateList (s : IStringLocalizer) =
|
||||
[ NoDisplay.toCode (), s.["Do not display the “as of” date"]
|
||||
ShortDate.toCode (), s.["Display a short “as of” date"]
|
||||
LongDate.toCode (), s.["Display a full “as of” date"]
|
||||
[ NoDisplay.code, s.["Do not display the “as of” date"]
|
||||
ShortDate.code, s.["Display a short “as of” date"]
|
||||
LongDate.code, s.["Display a full “as of” date"]
|
||||
]
|
||||
|
||||
/// A list of e-mail type options
|
||||
|
@ -289,7 +289,7 @@ with
|
|||
{ expireDays = prefs.daysToExpire
|
||||
daysToKeepNew = prefs.daysToKeepNew
|
||||
longTermUpdateWeeks = prefs.longTermUpdateWeeks
|
||||
requestSort = prefs.requestSort
|
||||
requestSort = prefs.requestSort.code
|
||||
emailFromName = prefs.emailFromName
|
||||
emailFromAddress = prefs.emailFromAddress
|
||||
defaultEmailType = prefs.defaultEmailType
|
||||
|
@ -303,7 +303,7 @@ with
|
|||
timeZone = prefs.timeZoneId
|
||||
groupPassword = Some prefs.groupPassword
|
||||
pageSize = prefs.pageSize
|
||||
asOfDate = prefs.asOfDateDisplay.toCode ()
|
||||
asOfDate = prefs.asOfDateDisplay.code
|
||||
listVisibility =
|
||||
match true with
|
||||
| _ when prefs.isPublic -> RequestVisibility.``public``
|
||||
|
@ -322,7 +322,7 @@ with
|
|||
daysToExpire = this.expireDays
|
||||
daysToKeepNew = this.daysToKeepNew
|
||||
longTermUpdateWeeks = this.longTermUpdateWeeks
|
||||
requestSort = this.requestSort
|
||||
requestSort = RequestSort.fromCode this.requestSort
|
||||
emailFromName = this.emailFromName
|
||||
emailFromAddress = this.emailFromAddress
|
||||
defaultEmailType = this.defaultEmailType
|
||||
|
@ -573,8 +573,8 @@ with
|
|||
|> Seq.ofList
|
||||
|> Seq.filter (fun req -> req.requestType = cat)
|
||||
match this.listGroup.preferences.requestSort with
|
||||
| "D" -> reqs |> Seq.sortByDescending (fun req -> req.updatedDate)
|
||||
| _ -> reqs |> Seq.sortBy (fun req -> req.requestor)
|
||||
| SortByDate -> reqs |> Seq.sortByDescending (fun req -> req.updatedDate)
|
||||
| SortByRequestor -> reqs |> Seq.sortBy (fun req -> req.requestor)
|
||||
|> List.ofSeq
|
||||
/// Is this request new?
|
||||
member this.isNew (req : PrayerRequest) =
|
||||
|
|
Loading…
Reference in New Issue
Block a user