Search, Paging, and "As of" Date (#10)

Issues Fixed:
* Added request search capability (#2)
* Added pagination to search / inactive request lists (#3)
* Added "as of" date display option for requests (#9)
* Updated documentation to reflect the new options and their behavior

Also Fixed (w/o issue numbers):
* Fixed a verbiage error with the confirmation prompts
* Split the I18N for the maintain requests page into its own localized view
* Modified many "magic strings" in the code to use F# discriminated unions instead (stored as single-character codes in the database)
This commit was merged in pull request #10.
This commit is contained in:
Daniel J. Summers
2019-03-20 19:19:02 -05:00
committed by GitHub
parent 6a6b403216
commit 43b6b6d8e0
28 changed files with 1176 additions and 356 deletions

View File

@@ -8,6 +8,22 @@ open PrayerTracker.Entities
open System.Collections.Generic
open System.Linq
[<AutoOpen>]
module private Helpers =
/// Central place to append sort criteria for prayer request queries
let reqSort sort (query : IQueryable<PrayerRequest>) =
match sort with
| 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)
type AppDbContext with
(*-- DISCONNECTED DATA EXTENSIONS --*)
@@ -64,7 +80,7 @@ type AppDbContext with
member this.CountMembersForSmallGroup gId =
this.Members.CountAsync (fun m -> m.smallGroupId = gId)
(*-- PRAYER REQUEST EXTENSIONS *)
(*-- PRAYER REQUEST EXTENSIONS --*)
/// Get a prayer request by its Id
member this.TryRequestById reqId =
@@ -74,32 +90,27 @@ type AppDbContext with
}
/// Get all (or active) requests for a small group as of now or the specified date
member this.AllRequestsForSmallGroup (grp : SmallGroup) clock listDate activeOnly : PrayerRequest seq =
member this.AllRequestsForSmallGroup (grp : SmallGroup) clock listDate activeOnly pageNbr : PrayerRequest seq =
let theDate = match listDate with Some dt -> dt | _ -> grp.localDateNow clock
upcast (
this.PrayerRequests.AsNoTracking().Where(fun pr -> pr.smallGroupId = grp.smallGroupId)
|> function
// Filter
| query when activeOnly ->
let asOf = theDate.AddDays(-(float grp.preferences.daysToExpire)).Date
query.Where(fun pr ->
(pr.updatedDate > asOf
|| pr.doNotExpire
|| RequestType.Recurring = pr.requestType
|| RequestType.Expecting = pr.requestType)
&& not pr.isManuallyExpired)
( pr.updatedDate > asOf
|| pr.expiration = Manual
|| pr.requestType = LongTermRequest
|| pr.requestType = Expecting)
&& pr.expiration <> Forced)
| query -> query
|> reqSort grp.preferences.requestSort
|> function
// Sort
| query when grp.preferences.requestSort = "D" ->
query.OrderByDescending(fun pr -> pr.updatedDate)
.ThenByDescending(fun pr -> pr.enteredDate)
.ThenBy(fun pr -> pr.requestor)
| query ->
query.OrderBy(fun pr -> pr.requestor)
.ThenByDescending(fun pr -> pr.updatedDate)
.ThenByDescending(fun pr -> pr.enteredDate))
match activeOnly with
| true -> query.Skip 0
| false -> query.Skip((pageNbr - 1) * grp.preferences.pageSize).Take grp.preferences.pageSize)
/// Count prayer requests for the given small group Id
member this.CountRequestsBySmallGroup gId =
this.PrayerRequests.CountAsync (fun pr -> pr.smallGroupId = gId)
@@ -108,6 +119,21 @@ type AppDbContext with
member this.CountRequestsByChurch cId =
this.PrayerRequests.CountAsync (fun pr -> pr.smallGroup.churchId = cId)
/// Get all (or active) requests for a small group as of now or the specified date
member this.SearchRequestsForSmallGroup (grp : SmallGroup) (searchTerm : string) pageNbr : PrayerRequest seq =
let pgSz = grp.preferences.pageSize
let skip = (pageNbr - 1) * pgSz
let sql =
""" SELECT * FROM pt."PrayerRequest" WHERE "SmallGroupId" = {0} AND "Text" ILIKE {1}
UNION
SELECT * FROM pt."PrayerRequest" WHERE "SmallGroupId" = {0} AND COALESCE("Requestor", '') ILIKE {1}"""
|> RawSqlString
let like = sprintf "%%%s%%"
upcast (
this.PrayerRequests.FromSql(sql, grp.smallGroupId, like searchTerm).AsNoTracking ()
|> reqSort grp.preferences.requestSort
|> function query -> (query.Skip skip).Take pgSz)
(*-- SMALL GROUP EXTENSIONS --*)
/// Find a small group by its Id

View File

@@ -6,37 +6,204 @@ open NodaTime
open System
open System.Collections.Generic
(*-- CONSTANTS --*)
/// Constants to use for the e-mail type parameter
[<RequireQualifiedAccess>]
module EmailType =
/// HTML e-mail
[<Literal>]
let Html = "Html"
/// Plain Text e-mail
[<Literal>]
let PlainText = "PlainText"
/// E-mail with the list as an attached PDF
[<Literal>]
let AttachedPdf = "AttachedPdf"
/// These values match those in the RequestType document store
[<RequireQualifiedAccess>]
module RequestType =
/// Current Requests (follow expiration rules)
let Current = "Current"
/// Long-Term / Recurring Requests (do not automatically expire)
let Recurring = "Recurring"
/// Praise Reports (follow expiration rules)
let Praise = "Praise"
/// Expectant Mothers (do not automatically expire)
let Expecting = "Expecting"
/// Announcements (follow expiration rules)
let Announcement = "Announcement"
(*-- SUPPORT TYPES --*)
/// How as-of dates should (or should not) be displayed with requests
type AsOfDateDisplay =
/// No as-of date should be displayed
| NoDisplay
/// The as-of date should be displayed in the culture's short date format
| ShortDate
/// The as-of date should be displayed in the culture's long date format
| LongDate
with
/// Convert to a DU case from a single-character string
static member fromCode code =
match code with
| "N" -> NoDisplay
| "S" -> ShortDate
| "L" -> LongDate
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string
member this.code =
match this with
| NoDisplay -> "N"
| ShortDate -> "S"
| LongDate -> "L"
/// Acceptable e-mail formats
type EmailFormat =
/// HTML e-mail
| HtmlFormat
/// Plain-text e-mail
| PlainTextFormat
with
/// Convert to a DU case from a single-character string
static member fromCode code =
match code with
| "H" -> HtmlFormat
| "P" -> PlainTextFormat
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string
member this.code =
match this with
| HtmlFormat -> "H"
| PlainTextFormat -> "P"
/// Expiration for requests
type Expiration =
/// Follow the rules for normal expiration
| Automatic
/// Do not expire via rules
| Manual
/// Force immediate expiration
| Forced
with
/// Convert to a DU case from a single-character string
static member fromCode code =
match code with
| "A" -> Automatic
| "M" -> Manual
| "F" -> Forced
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string
member this.code =
match this with
| Automatic -> "A"
| Manual -> "M"
| Forced -> "F"
/// Types of prayer requests
type PrayerRequestType =
/// Current requests
| CurrentRequest
/// Long-term/ongoing request
| LongTermRequest
/// Expectant couples
| Expecting
/// Praise reports
| PraiseReport
/// Announcements
| Announcement
with
/// Convert to a DU case from a single-character string
static member fromCode code =
match code with
| "C" -> CurrentRequest
| "L" -> LongTermRequest
| "E" -> Expecting
| "P" -> PraiseReport
| "A" -> Announcement
| _ -> invalidArg "code" (sprintf "Unknown code %s" code)
/// Convert this DU case to a single-character string
member this.code =
match this with
| CurrentRequest -> "C"
| LongTermRequest -> "L"
| Expecting -> "E"
| PraiseReport -> "P"
| Announcement -> "A"
/// 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 asOfFromDU =
<@ Func<AsOfDateDisplay, string>(fun (x : AsOfDateDisplay) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<AsOfDateDisplay, string>>>
let private asOfToDU =
<@ Func<string, AsOfDateDisplay>(AsOfDateDisplay.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, AsOfDateDisplay>>>
let private emailFromDU =
<@ Func<EmailFormat, string>(fun (x : EmailFormat) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<EmailFormat, string>>>
let private emailToDU =
<@ Func<string, EmailFormat>(EmailFormat.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, EmailFormat>>>
let private expFromDU =
<@ Func<Expiration, string>(fun (x : Expiration) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<Expiration, string>>>
let private expToDU =
<@ Func<string, Expiration>(Expiration.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, Expiration>>>
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>>>
let private typFromDU =
<@ Func<PrayerRequestType, string>(fun (x : PrayerRequestType) -> x.code) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<PrayerRequestType, string>>>
let private typToDU =
<@ Func<string, PrayerRequestType>(PrayerRequestType.fromCode) @>
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<Func<string, PrayerRequestType>>>
/// Conversion between a string and an AsOfDateDisplay DU value
type AsOfDateDisplayConverter () =
inherit ValueConverter<AsOfDateDisplay, string> (asOfFromDU, asOfToDU)
/// Conversion between a string and an EmailFormat DU value
type EmailFormatConverter () =
inherit ValueConverter<EmailFormat, string> (emailFromDU, emailToDU)
/// Conversion between a string and an Expiration DU value
type ExpirationConverter () =
inherit ValueConverter<Expiration, string> (expFromDU, expToDU)
/// Conversion between a string and an AsOfDateDisplay DU value
type PrayerRequestTypeConverter () =
inherit ValueConverter<PrayerRequestType, string> (typFromDU, typToDU)
/// Conversion between a string and a RequestSort DU value
type RequestSortConverter () =
inherit ValueConverter<RequestSort, string> (sortFromDU, sortToDU)
/// Statistics for churches
[<NoComparison; NoEquality>]
type ChurchStats =
@@ -145,17 +312,21 @@ 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
defaultEmailType : string
defaultEmailType : EmailFormat
/// Whether this class makes its request list public
isPublic : bool
/// The time zone which this class uses (use tzdata names)
timeZoneId : TimeZoneId
/// The time zone information
timeZone : TimeZone
/// The number of requests displayed per page
pageSize : int
/// How the as-of date should be automatically displayed
asOfDateDisplay : AsOfDateDisplay
}
with
/// A set of preferences with their default values
@@ -171,12 +342,14 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
lineColor = "navy"
headingFontSize = 16
textFontSize = 12
requestSort = "D"
requestSort = SortByDate
groupPassword = ""
defaultEmailType = EmailType.Html
defaultEmailType = HtmlFormat
isPublic = false
timeZoneId = "America/Denver"
timeZone = TimeZone.empty
pageSize = 100
asOfDateDisplay = NoDisplay
}
/// Configure EF for this entity
static member internal configureEF (mb : ModelBuilder) =
@@ -188,80 +361,97 @@ and [<CLIMutable; NoComparison; NoEquality>] ListPreferences =
m.Property(fun e -> e.daysToKeepNew)
.HasColumnName("DaysToKeepNew")
.IsRequired()
.HasDefaultValue(7)
.HasDefaultValue 7
|> ignore
m.Property(fun e -> e.daysToExpire)
.HasColumnName("DaysToExpire")
.IsRequired()
.HasDefaultValue(14)
.HasDefaultValue 14
|> ignore
m.Property(fun e -> e.longTermUpdateWeeks)
.HasColumnName("LongTermUpdateWeeks")
.IsRequired()
.HasDefaultValue(4)
.HasDefaultValue 4
|> ignore
m.Property(fun e -> e.emailFromName)
.HasColumnName("EmailFromName")
.IsRequired()
.HasDefaultValue("PrayerTracker")
.HasDefaultValue "PrayerTracker"
|> ignore
m.Property(fun e -> e.emailFromAddress)
.HasColumnName("EmailFromAddress")
.IsRequired()
.HasDefaultValue("prayer@djs-consulting.com")
.HasDefaultValue "prayer@djs-consulting.com"
|> ignore
m.Property(fun e -> e.listFonts)
.HasColumnName("ListFonts")
.IsRequired()
.HasDefaultValue("Century Gothic,Tahoma,Luxi Sans,sans-serif")
.HasDefaultValue "Century Gothic,Tahoma,Luxi Sans,sans-serif"
|> ignore
m.Property(fun e -> e.headingColor)
.HasColumnName("HeadingColor")
.IsRequired()
.HasDefaultValue("maroon")
.HasDefaultValue "maroon"
|> ignore
m.Property(fun e -> e.lineColor)
.HasColumnName("LineColor")
.IsRequired()
.HasDefaultValue("navy")
.HasDefaultValue "navy"
|> ignore
m.Property(fun e -> e.headingFontSize)
.HasColumnName("HeadingFontSize")
.IsRequired()
.HasDefaultValue(16)
.HasDefaultValue 16
|> ignore
m.Property(fun e -> e.textFontSize)
.HasColumnName("TextFontSize")
.IsRequired()
.HasDefaultValue(12)
.HasDefaultValue 12
|> ignore
m.Property(fun e -> e.requestSort)
.HasColumnName("RequestSort")
.IsRequired()
.HasMaxLength(1)
.HasDefaultValue("D")
.HasDefaultValue SortByDate
|> ignore
m.Property(fun e -> e.groupPassword)
.HasColumnName("GroupPassword")
.IsRequired()
.HasDefaultValue("")
.HasDefaultValue ""
|> ignore
m.Property(fun e -> e.defaultEmailType)
.HasColumnName("DefaultEmailType")
.IsRequired()
.HasDefaultValue(EmailType.Html)
.HasDefaultValue HtmlFormat
|> ignore
m.Property(fun e -> e.isPublic)
.HasColumnName("IsPublic")
.IsRequired()
.HasDefaultValue(false)
.HasDefaultValue false
|> ignore
m.Property(fun e -> e.timeZoneId)
.HasColumnName("TimeZoneId")
.IsRequired()
.HasDefaultValue("America/Denver")
.HasDefaultValue "America/Denver"
|> ignore
m.Property(fun e -> e.pageSize)
.HasColumnName("PageSize")
.IsRequired()
.HasDefaultValue 100
|> ignore
m.Property(fun e -> e.asOfDateDisplay)
.HasColumnName("AsOfDateDisplay")
.IsRequired()
.HasMaxLength(1)
.HasDefaultValue NoDisplay
|> ignore)
|> ignore
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("requestSort")
.SetValueConverter(Converters.RequestSortConverter ())
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("defaultEmailType")
.SetValueConverter(Converters.EmailFormatConverter ())
mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("asOfDateDisplay")
.SetValueConverter(Converters.AsOfDateDisplayConverter ())
/// A member of a small group
@@ -275,7 +465,7 @@ and [<CLIMutable; NoComparison; NoEquality>] Member =
/// The e-mail address for the member
email : string
/// The type of e-mail preferred by this member (see <see cref="EmailTypes"/> constants)
format : string option
format : string option // TODO - do I need a custom formatter for this?
/// The small group to which this member belongs
smallGroup : SmallGroup
}
@@ -306,64 +496,62 @@ and [<CLIMutable; NoComparison; NoEquality>] Member =
/// This represents a single prayer request
and [<CLIMutable; NoComparison; NoEquality>] PrayerRequest =
{ /// The Id of this request
prayerRequestId : PrayerRequestId
prayerRequestId : PrayerRequestId
/// The type of the request
requestType : string
requestType : PrayerRequestType
/// The user who entered the request
userId : UserId
userId : UserId
/// The small group to which this request belongs
smallGroupId : SmallGroupId
smallGroupId : SmallGroupId
/// The date/time on which this request was entered
enteredDate : DateTime
enteredDate : DateTime
/// The date/time this request was last updated
updatedDate : DateTime
updatedDate : DateTime
/// The name of the requestor or subject, or title of announcement
requestor : string option
requestor : string option
/// The text of the request
text : string
/// Whether this request is exempt from standard expiration rules
doNotExpire : bool
text : string
/// Whether the chaplain should be notified for this request
notifyChaplain : bool
/// Whether this request has been expired manually
isManuallyExpired : bool
notifyChaplain : bool
/// The user who entered this request
user : User
user : User
/// The small group to which this request belongs
smallGroup : SmallGroup
smallGroup : SmallGroup
/// Is this request expired?
expiration : Expiration
}
with
/// An empty request
static member empty =
{ prayerRequestId = Guid.Empty
requestType = RequestType.Current
userId = Guid.Empty
smallGroupId = Guid.Empty
enteredDate = DateTime.MinValue
updatedDate = DateTime.MinValue
requestor = None
text = ""
doNotExpire = false
notifyChaplain = false
isManuallyExpired = false
user = User.empty
smallGroup = SmallGroup.empty
{ prayerRequestId = Guid.Empty
requestType = CurrentRequest
userId = Guid.Empty
smallGroupId = Guid.Empty
enteredDate = DateTime.MinValue
updatedDate = DateTime.MinValue
requestor = None
text = ""
notifyChaplain = false
user = User.empty
smallGroup = SmallGroup.empty
expiration = Automatic
}
/// Is this request expired?
member this.isExpired (curr : DateTime) expDays =
match this.isManuallyExpired with
| true -> true // Manual expiration
| false ->
let nonExpiringTypes = [ RequestType.Recurring; RequestType.Expecting ]
match this.doNotExpire || List.contains this.requestType nonExpiringTypes with
| true -> false // No expiration
| false -> curr.AddDays(-(float expDays)) > this.updatedDate // Automatic expiration
match this.expiration with
| Forced -> true
| Manual -> false
| Automatic ->
match this.requestType with
| LongTermRequest
| Expecting -> false
| _ -> curr.AddDays(-(float expDays)) > this.updatedDate // Automatic expiration
/// Is an update required for this long-term request?
member this.updateRequired curr expDays updWeeks =
match this.isExpired curr expDays with
| true -> false
| _ -> curr.AddDays(-(float (updWeeks * 7))) > this.updatedDate
| false -> curr.AddDays(-(float (updWeeks * 7))) > this.updatedDate
/// Configure EF for this entity
static member internal configureEF (mb : ModelBuilder) =
@@ -378,12 +566,15 @@ and [<CLIMutable; NoComparison; NoEquality>] PrayerRequest =
m.Property(fun e -> e.updatedDate).HasColumnName "UpdatedDate" |> ignore
m.Property(fun e -> e.requestor).HasColumnName "Requestor" |> ignore
m.Property(fun e -> e.text).HasColumnName("Text").IsRequired() |> ignore
m.Property(fun e -> e.doNotExpire).HasColumnName "DoNotExpire" |> ignore
m.Property(fun e -> e.notifyChaplain).HasColumnName "NotifyChaplain" |> ignore
m.Property(fun e -> e.isManuallyExpired).HasColumnName "IsManuallyExpired" |> ignore)
m.Property(fun e -> e.expiration).HasColumnName "Expiration" |> ignore)
|> ignore
mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("requestType")
.SetValueConverter(Converters.PrayerRequestTypeConverter ())
mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("requestor")
.SetValueConverter(OptionConverter<string> ())
mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("expiration")
.SetValueConverter(Converters.ExpirationConverter ())
/// This represents a small group (Sunday School class, Bible study group, etc.)

View File

@@ -37,6 +37,8 @@ type ListPreferencesTable =
requestSort : OperationBuilder<AddColumnOperation>
textFontSize : OperationBuilder<AddColumnOperation>
timeZoneId : OperationBuilder<AddColumnOperation>
pageSize : OperationBuilder<AddColumnOperation>
asOfDateDisplay : OperationBuilder<AddColumnOperation>
}
type MemberTable =
@@ -48,17 +50,16 @@ type MemberTable =
}
type PrayerRequestTable =
{ prayerRequestId : OperationBuilder<AddColumnOperation>
doNotExpire : OperationBuilder<AddColumnOperation>
enteredDate : OperationBuilder<AddColumnOperation>
isManuallyExpired : OperationBuilder<AddColumnOperation>
notifyChaplain : OperationBuilder<AddColumnOperation>
requestType : OperationBuilder<AddColumnOperation>
requestor : OperationBuilder<AddColumnOperation>
smallGroupId : OperationBuilder<AddColumnOperation>
text : OperationBuilder<AddColumnOperation>
updatedDate : OperationBuilder<AddColumnOperation>
userId : OperationBuilder<AddColumnOperation>
{ prayerRequestId : OperationBuilder<AddColumnOperation>
enteredDate : OperationBuilder<AddColumnOperation>
expiration : OperationBuilder<AddColumnOperation>
notifyChaplain : OperationBuilder<AddColumnOperation>
requestType : OperationBuilder<AddColumnOperation>
requestor : OperationBuilder<AddColumnOperation>
smallGroupId : OperationBuilder<AddColumnOperation>
text : OperationBuilder<AddColumnOperation>
updatedDate : OperationBuilder<AddColumnOperation>
userId : OperationBuilder<AddColumnOperation>
}
type SmallGroupTable =
@@ -102,12 +103,12 @@ type InitialDatabase () =
schema = "pt",
columns =
(fun table ->
{ churchId = table.Column<Guid> (name = "ChurchId", nullable = false)
city = table.Column<string> (name = "City", nullable = false)
{ churchId = table.Column<Guid> (name = "ChurchId", nullable = false)
city = table.Column<string> (name = "City", nullable = false)
hasInterface = table.Column<bool> (name = "HasVirtualPrayerRoomInterface", nullable = false)
interfaceAddress = table.Column<string> (name = "InterfaceAddress", nullable = true)
name = table.Column<string> (name = "Name", nullable = false)
st = table.Column<string> (name = "ST", maxLength = Nullable<int> 2, nullable = false)
name = table.Column<string> (name = "Name", nullable = false)
st = table.Column<string> (name = "ST", nullable = false, maxLength = Nullable<int> 2)
}),
constraints =
fun table ->
@@ -119,10 +120,10 @@ type InitialDatabase () =
schema = "pt",
columns =
(fun table ->
{ timeZoneId = table.Column<string> (name = "TimeZoneId", nullable = false)
{ timeZoneId = table.Column<string> (name = "TimeZoneId", nullable = false)
description = table.Column<string> (name = "Description", nullable = false)
isActive = table.Column<bool> (name = "IsActive", nullable = false)
sortOrder = table.Column<int> (name = "SortOrder", nullable = false)
isActive = table.Column<bool> (name = "IsActive", nullable = false)
sortOrder = table.Column<int> (name = "SortOrder", nullable = false)
}),
constraints =
fun table ->
@@ -134,13 +135,13 @@ type InitialDatabase () =
schema = "pt",
columns =
(fun table ->
{ userId = table.Column<Guid> (name = "UserId", nullable = false)
emailAddress = table.Column<string> (name = "EmailAddress", nullable = false)
firstName = table.Column<string> (name = "FirstName", nullable = false)
{ userId = table.Column<Guid> (name = "UserId", nullable = false)
emailAddress = table.Column<string> (name = "EmailAddress", nullable = false)
firstName = table.Column<string> (name = "FirstName", nullable = false)
isAdmin = table.Column<bool> (name = "IsSystemAdmin", nullable = false)
lastName = table.Column<string> (name = "LastName", nullable = false)
passwordHash = table.Column<string> (name = "PasswordHash", nullable = false)
salt = table.Column<Guid> (name = "Salt", nullable = true)
lastName = table.Column<string> (name = "LastName", nullable = false)
passwordHash = table.Column<string> (name = "PasswordHash", nullable = false)
salt = table.Column<Guid> (name = "Salt", nullable = true)
}),
constraints =
fun table ->
@@ -153,8 +154,8 @@ type InitialDatabase () =
columns =
(fun table ->
{ smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false)
churchId = table.Column<Guid> (name = "ChurchId", nullable = false)
name = table.Column<string> (name = "Name", nullable = false)
churchId = table.Column<Guid> (name = "ChurchId", nullable = false)
name = table.Column<string> (name = "Name", nullable = false)
}),
constraints =
fun table ->
@@ -174,22 +175,24 @@ type InitialDatabase () =
schema = "pt",
columns =
(fun table ->
{ smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false)
daysToExpire = table.Column<int> (name = "DaysToExpire", nullable = false, defaultValue = 14)
daysToKeepNew = table.Column<int> (name = "DaysToKeepNew", nullable = false, defaultValue = 7)
defaultEmailType = table.Column<string> (name = "DefaultEmailType", nullable = false, defaultValue = "Html")
emailFromAddress = table.Column<string> (name = "EmailFromAddress", nullable = false, defaultValue = "prayer@djs-consulting.com")
emailFromName = table.Column<string> (name = "EmailFromName", nullable = false, defaultValue = "PrayerTracker")
groupPassword = table.Column<string> (name = "GroupPassword", nullable = false, defaultValue = "")
headingColor = table.Column<string> (name = "HeadingColor", nullable = false, defaultValue = "maroon")
headingFontSize = table.Column<int> (name = "HeadingFontSize", nullable = false, defaultValue = 16)
isPublic = table.Column<bool> (name = "IsPublic", nullable = false, defaultValue = false)
lineColor = table.Column<string> (name = "LineColor", nullable = false, defaultValue = "navy")
listFonts = table.Column<string> (name = "ListFonts", nullable = false, defaultValue = "Century Gothic,Tahoma,Luxi Sans,sans-serif")
{ smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false)
daysToExpire = table.Column<int> (name = "DaysToExpire", nullable = false, defaultValue = 14)
daysToKeepNew = table.Column<int> (name = "DaysToKeepNew", nullable = false, defaultValue = 7)
defaultEmailType = table.Column<string> (name = "DefaultEmailType", nullable = false, defaultValue = "Html")
emailFromAddress = table.Column<string> (name = "EmailFromAddress", nullable = false, defaultValue = "prayer@djs-consulting.com")
emailFromName = table.Column<string> (name = "EmailFromName", nullable = false, defaultValue = "PrayerTracker")
groupPassword = table.Column<string> (name = "GroupPassword", nullable = false, defaultValue = "")
headingColor = table.Column<string> (name = "HeadingColor", nullable = false, defaultValue = "maroon")
headingFontSize = table.Column<int> (name = "HeadingFontSize", nullable = false, defaultValue = 16)
isPublic = table.Column<bool> (name = "IsPublic", nullable = false, defaultValue = false)
lineColor = table.Column<string> (name = "LineColor", nullable = false, defaultValue = "navy")
listFonts = table.Column<string> (name = "ListFonts", nullable = false, defaultValue = "Century Gothic,Tahoma,Luxi Sans,sans-serif")
longTermUpdateWeeks = table.Column<int> (name = "LongTermUpdateWeeks", nullable = false, defaultValue = 4)
requestSort = table.Column<string> (name = "RequestSort", maxLength = Nullable<int> 1, nullable = false, defaultValue = "D")
textFontSize = table.Column<int> (name = "TextFontSize", nullable = false, defaultValue = 12)
timeZoneId = table.Column<string> (name = "TimeZoneId", nullable = false, defaultValue = "America/Denver")
requestSort = table.Column<string> (name = "RequestSort", nullable = false, defaultValue = "D", maxLength = Nullable<int> 1)
textFontSize = table.Column<int> (name = "TextFontSize", nullable = false, defaultValue = 12)
timeZoneId = table.Column<string> (name = "TimeZoneId", nullable = false, defaultValue = "America/Denver")
pageSize = table.Column<int> (name = "PageSize", nullable = false, defaultValue = 100)
asOfDateDisplay = table.Column<string> (name = "AsOfDateDisplay", nullable = false, defaultValue = "N", maxLength = Nullable<int> 1)
}),
constraints =
fun table ->
@@ -217,10 +220,10 @@ type InitialDatabase () =
schema = "pt",
columns =
(fun table ->
{ memberId = table.Column<Guid> (name = "MemberId", nullable = false)
email = table.Column<string> (name = "Email", nullable = false)
format = table.Column<string> (name = "Format", nullable = true)
memberName = table.Column<string> (name = "MemberName", nullable = false)
{ memberId = table.Column<Guid> (name = "MemberId", nullable = false)
email = table.Column<string> (name = "Email", nullable = false)
format = table.Column<string> (name = "Format", nullable = true)
memberName = table.Column<string> (name = "MemberName", nullable = false)
smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false)
}),
constraints =
@@ -242,16 +245,15 @@ type InitialDatabase () =
columns =
(fun table ->
{ prayerRequestId = table.Column<Guid> (name = "PrayerRequestId", nullable = false)
doNotExpire = table.Column<bool> (name = "DoNotExpire", nullable = false)
enteredDate = table.Column<DateTime> (name = "EnteredDate", nullable = false)
isManuallyExpired = table.Column<bool> (name = "IsManuallyExpired", nullable = false)
notifyChaplain = table.Column<bool> (name = "NotifyChaplain", nullable = false)
requestType = table.Column<string> (name = "RequestType", nullable = false)
requestor = table.Column<string> (name = "Requestor", nullable = true)
smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false)
text = table.Column<string> (name = "Text", nullable = false)
updatedDate = table.Column<DateTime> (name = "UpdatedDate", nullable = false)
userId = table.Column<Guid> (name = "UserId", nullable = false)
expiration = table.Column<bool> (name = "Expiration", nullable = false)
enteredDate = table.Column<DateTime> (name = "EnteredDate", nullable = false)
notifyChaplain = table.Column<bool> (name = "NotifyChaplain", nullable = false)
requestType = table.Column<string> (name = "RequestType", nullable = false)
requestor = table.Column<string> (name = "Requestor", nullable = true)
smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false)
text = table.Column<string> (name = "Text", nullable = false)
updatedDate = table.Column<DateTime> (name = "UpdatedDate", nullable = false)
userId = table.Column<Guid> (name = "UserId", nullable = false)
}),
constraints =
fun table ->
@@ -279,7 +281,7 @@ type InitialDatabase () =
schema = "pt",
columns =
(fun table ->
{ userId = table.Column<Guid> (name = "UserId", nullable = false)
{ userId = table.Column<Guid> (name = "UserId", nullable = false)
smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false)
}),
constraints =
@@ -347,7 +349,7 @@ type InitialDatabase () =
b.Property<Guid>("smallGroupId") |> ignore
b.Property<int>("daysToExpire").ValueGeneratedOnAdd().HasDefaultValue(14) |> ignore
b.Property<int>("daysToKeepNew").ValueGeneratedOnAdd().HasDefaultValue(7) |> ignore
b.Property<string>("defaultEmailType").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("Html") |> ignore
b.Property<string>("defaultEmailType").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("H") |> ignore
b.Property<string>("emailFromAddress").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("prayer@djs-consulting.com") |> ignore
b.Property<string>("emailFromName").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("PrayerTracker") |> ignore
b.Property<string>("groupPassword").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("") |> ignore
@@ -357,9 +359,11 @@ type InitialDatabase () =
b.Property<string>("lineColor").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("navy") |> ignore
b.Property<string>("listFonts").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("Century Gothic,Tahoma,Luxi Sans,sans-serif") |> ignore
b.Property<int>("longTermUpdateWeeks").ValueGeneratedOnAdd().HasDefaultValue(4) |> ignore
b.Property<string>("requestSort").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("D").HasMaxLength(1) |> ignore
b.Property<string>("requestSort").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("D").HasMaxLength(1) |> ignore
b.Property<int>("textFontSize").ValueGeneratedOnAdd().HasDefaultValue(12) |> ignore
b.Property<string>("timeZoneId").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("America/Denver") |> ignore
b.Property<int>("pageSize").IsRequired().ValueGeneratedOnAdd().HasDefaultValue(100) |> ignore
b.Property<string>("asOfDateDisplay").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("N").HasMaxLength(1) |> ignore
b.HasKey("smallGroupId") |> ignore
b.HasIndex("timeZoneId") |> ignore
b.ToTable("ListPreference") |> ignore)
@@ -382,11 +386,10 @@ type InitialDatabase () =
typeof<PrayerRequest>,
fun b ->
b.Property<Guid>("prayerRequestId").ValueGeneratedOnAdd() |> ignore
b.Property<bool>("doNotExpire") |> ignore
b.Property<DateTime>("enteredDate") |> ignore
b.Property<bool>("isManuallyExpired") |> ignore
b.Property<DateTime>("enteredDate").IsRequired() |> ignore
b.Property<string>("expiration").IsRequired().HasMaxLength 1 |> ignore
b.Property<bool>("notifyChaplain") |> ignore
b.Property<string>("requestType").IsRequired() |> ignore
b.Property<string>("requestType").IsRequired().HasMaxLength 1 |> ignore
b.Property<string>("requestor") |> ignore
b.Property<Guid>("smallGroupId") |> ignore
b.Property<string>("text").IsRequired() |> ignore

View File

@@ -36,7 +36,7 @@ type AppDbContextModelSnapshot () =
b.Property<Guid>("smallGroupId") |> ignore
b.Property<int>("daysToExpire").ValueGeneratedOnAdd().HasDefaultValue(14) |> ignore
b.Property<int>("daysToKeepNew").ValueGeneratedOnAdd().HasDefaultValue(7) |> ignore
b.Property<string>("defaultEmailType").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("Html") |> ignore
b.Property<string>("defaultEmailType").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("H").HasMaxLength(1) |> ignore
b.Property<string>("emailFromAddress").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("prayer@djs-consulting.com") |> ignore
b.Property<string>("emailFromName").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("PrayerTracker") |> ignore
b.Property<string>("groupPassword").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("") |> ignore
@@ -46,9 +46,11 @@ type AppDbContextModelSnapshot () =
b.Property<string>("lineColor").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("navy") |> ignore
b.Property<string>("listFonts").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("Century Gothic,Tahoma,Luxi Sans,sans-serif") |> ignore
b.Property<int>("longTermUpdateWeeks").ValueGeneratedOnAdd().HasDefaultValue(4) |> ignore
b.Property<string>("requestSort").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("D").HasMaxLength(1) |> ignore
b.Property<string>("requestSort").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("D").HasMaxLength(1) |> ignore
b.Property<int>("textFontSize").ValueGeneratedOnAdd().HasDefaultValue(12) |> ignore
b.Property<string>("timeZoneId").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("America/Denver") |> ignore
b.Property<int>("pageSize").IsRequired().ValueGeneratedOnAdd().HasDefaultValue(100) |> ignore
b.Property<string>("asOfDateDisplay").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("N").HasMaxLength(1) |> ignore
b.HasKey("smallGroupId") |> ignore
b.HasIndex("timeZoneId") |> ignore
b.ToTable("ListPreference") |> ignore)
@@ -71,11 +73,10 @@ type AppDbContextModelSnapshot () =
typeof<PrayerRequest>,
fun b ->
b.Property<Guid>("prayerRequestId").ValueGeneratedOnAdd() |> ignore
b.Property<bool>("doNotExpire") |> ignore
b.Property<DateTime>("enteredDate") |> ignore
b.Property<bool>("isManuallyExpired") |> ignore
b.Property<string>("expiration").IsRequired().HasMaxLength(1) |> ignore
b.Property<bool>("notifyChaplain") |> ignore
b.Property<string>("requestType").IsRequired() |> ignore
b.Property<string>("requestType").IsRequired().HasMaxLength(1) |> ignore
b.Property<string>("requestor") |> ignore
b.Property<Guid>("smallGroupId") |> ignore
b.Property<string>("text").IsRequired() |> ignore

View File

@@ -2,8 +2,8 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyVersion>7.0.0.0</AssemblyVersion>
<FileVersion>7.0.0.0</FileVersion>
<AssemblyVersion>7.3.0.0</AssemblyVersion>
<FileVersion>7.3.0.0</FileVersion>
</PropertyGroup>
<ItemGroup>