diff --git a/src/PrayerTracker.Data/Access.fs b/src/PrayerTracker.Data/Access.fs index a9e6163..d08e68d 100644 --- a/src/PrayerTracker.Data/Access.fs +++ b/src/PrayerTracker.Data/Access.fs @@ -36,9 +36,9 @@ module private Helpers = IsPublic = row.bool "is_public" PageSize = row.int "page_size" TimeZoneId = TimeZoneId (row.string "time_zone_id") - RequestSort = RequestSort.fromCode (row.string "request_sort") - DefaultEmailType = EmailFormat.fromCode (row.string "default_email_type") - AsOfDateDisplay = AsOfDateDisplay.fromCode (row.string "as_of_date_display") + RequestSort = RequestSort.Parse (row.string "request_sort") + DefaultEmailType = EmailFormat.Parse (row.string "default_email_type") + AsOfDateDisplay = AsOfDateDisplay.Parse (row.string "as_of_date_display") } /// Map a row to a Member instance @@ -47,7 +47,7 @@ module private Helpers = SmallGroupId = SmallGroupId (row.uuid "small_group_id") Name = row.string "member_name" Email = row.string "email" - Format = row.stringOrNone "email_format" |> Option.map EmailFormat.fromCode + Format = row.stringOrNone "email_format" |> Option.map EmailFormat.Parse } /// Map a row to a Prayer Request instance @@ -60,8 +60,8 @@ module private Helpers = Requestor = row.stringOrNone "requestor" Text = row.string "request_text" NotifyChaplain = row.bool "notify_chaplain" - RequestType = PrayerRequestType.fromCode (row.string "request_type") - Expiration = Expiration.fromCode (row.string "expiration") + RequestType = PrayerRequestType.Parse (row.string "request_type") + Expiration = Expiration.Parse (row.string "expiration") } /// Map a row to a Small Group instance @@ -185,7 +185,7 @@ module Members = "@groupId", Sql.uuid mbr.SmallGroupId.Value "@name", Sql.string mbr.Name "@email", Sql.string mbr.Email - "@format", Sql.stringOrNone (mbr.Format |> Option.map EmailFormat.toCode) ] + "@format", Sql.stringOrNone (mbr.Format |> Option.map string) ] /// Retrieve a small group member by its ID let tryById (memberId : MemberId) = @@ -257,10 +257,10 @@ module PrayerRequests = OR request_type = @expecting) AND expiration <> @forced", [ "@asOf", Sql.parameter asOf - "@manual", Sql.string (Expiration.toCode Manual) - "@longTerm", Sql.string (PrayerRequestType.toCode LongTermRequest) - "@expecting", Sql.string (PrayerRequestType.toCode Expecting) - "@forced", Sql.string (Expiration.toCode Forced) ] + "@manual", Sql.string (string Manual) + "@longTerm", Sql.string (string LongTermRequest) + "@expecting", Sql.string (string Expecting) + "@forced", Sql.string (string Forced) ] else "", [] Custom.list $"SELECT * @@ -287,15 +287,15 @@ module PrayerRequests = notify_chaplain = EXCLUDED.notify_chaplain, expiration = EXCLUDED.expiration" [ "@id", Sql.uuid req.Id.Value - "@type", Sql.string (PrayerRequestType.toCode req.RequestType) + "@type", Sql.string (string req.RequestType) "@userId", Sql.uuid req.UserId.Value "@groupId", Sql.uuid req.SmallGroupId.Value - "@entered", Sql.parameter (NpgsqlParameter ("@entered", req.EnteredDate)) - "@updated", Sql.parameter (NpgsqlParameter ("@updated", req.UpdatedDate)) + "@entered", Sql.parameter (NpgsqlParameter("@entered", req.EnteredDate)) + "@updated", Sql.parameter (NpgsqlParameter("@updated", req.UpdatedDate)) "@requestor", Sql.stringOrNone req.Requestor "@text", Sql.string req.Text "@notifyChaplain", Sql.bool req.NotifyChaplain - "@expiration", Sql.string (Expiration.toCode req.Expiration) ] + "@expiration", Sql.string (string req.Expiration) ] /// Search prayer requests for the given term let searchForGroup group searchTerm pageNbr = @@ -320,9 +320,8 @@ module PrayerRequests = [ "@updated", Sql.parameter (NpgsqlParameter ("@updated", req.UpdatedDate)) ] else "", [] Custom.nonQuery $"UPDATE pt.prayer_request SET expiration = @expiration{sql} WHERE id = @id" - ([ "@expiration", Sql.string (Expiration.toCode req.Expiration) - "@id", Sql.uuid req.Id.Value ] - |> List.append parameters) + ([ "@expiration", Sql.string (string req.Expiration); "@id", Sql.uuid req.Id.Value ] + |> List.append parameters) /// Functions to retrieve small group information @@ -455,13 +454,13 @@ module SmallGroups = "@lineColor", Sql.string pref.LineColor "@headingFontSize", Sql.int pref.HeadingFontSize "@textFontSize", Sql.int pref.TextFontSize - "@requestSort", Sql.string (RequestSort.toCode pref.RequestSort) + "@requestSort", Sql.string (string pref.RequestSort) "@groupPassword", Sql.string pref.GroupPassword - "@defaultEmailType", Sql.string (EmailFormat.toCode pref.DefaultEmailType) + "@defaultEmailType", Sql.string (string pref.DefaultEmailType) "@isPublic", Sql.bool pref.IsPublic "@timeZoneId", Sql.string (TimeZoneId.toString pref.TimeZoneId) "@pageSize", Sql.int pref.PageSize - "@asOfDateDisplay", Sql.string (AsOfDateDisplay.toCode pref.AsOfDateDisplay) ] + "@asOfDateDisplay", Sql.string (string pref.AsOfDateDisplay) ] /// Get a small group by its ID let tryById (groupId : SmallGroupId) = diff --git a/src/PrayerTracker.Data/Entities.fs b/src/PrayerTracker.Data/Entities.fs index 29bcfd1..aaf7e0a 100644 --- a/src/PrayerTracker.Data/Entities.fs +++ b/src/PrayerTracker.Data/Entities.fs @@ -11,19 +11,20 @@ type AsOfDateDisplay = /// The as-of date should be displayed in the culture's long date format | LongDate -/// Functions to support as-of date display options -module AsOfDateDisplay = - - /// Convert to a DU case from a single-character string - let fromCode code = + /// Convert this to a single-character code + override this.ToString() = + match this with + | NoDisplay -> "N" + | ShortDate -> "S" + | LongDate -> "L" + + /// Create an AsOfDateDisplay from a single-character code + static member Parse code = match code with | "N" -> NoDisplay | "S" -> ShortDate | "L" -> LongDate - | _ -> invalidArg "code" $"Unknown code {code}" - - /// Convert this DU case to a single-character string - let toCode = function NoDisplay -> "N" | ShortDate -> "S" | LongDate -> "L" + | _ -> invalidArg "code" $"Unknown code {code}" /// Acceptable e-mail formats @@ -33,18 +34,18 @@ type EmailFormat = /// Plain-text e-mail | PlainTextFormat -/// Functions to support e-mail formats -module EmailFormat = - - /// Convert to a DU case from a single-character string - let fromCode code = + /// Convert this to a single-character code + override this.ToString() = + match this with + | HtmlFormat -> "H" + | PlainTextFormat -> "P" + + /// Create an EmailFormat from a single-character code + static member Parse code = match code with | "H" -> HtmlFormat | "P" -> PlainTextFormat - | _ -> invalidArg "code" $"Unknown code {code}" - - /// Convert this DU case to a single-character string - let toCode = function HtmlFormat -> "H" | PlainTextFormat -> "P" + | _ -> invalidArg "code" $"Unknown code {code}" /// Expiration for requests @@ -56,19 +57,20 @@ type Expiration = /// Force immediate expiration | Forced -/// Functions to support expirations -module Expiration = - - /// Convert to a DU case from a single-character string - let fromCode code = + /// Convert this to a single-character code + override this.ToString() = + match this with + | Automatic -> "A" + | Manual -> "M" + | Forced -> "F" + + /// Create an Expiration from a single-character code + static member Parse code = match code with | "A" -> Automatic | "M" -> Manual | "F" -> Forced - | _ -> invalidArg "code" $"Unknown code {code}" - - /// Convert this DU case to a single-character string - let toCode = function Automatic -> "A" | Manual -> "M" | Forced -> "F" + | _ -> invalidArg "code" $"Unknown code {code}" /// Types of prayer requests @@ -84,27 +86,24 @@ type PrayerRequestType = /// Announcements | Announcement -/// Functions to support prayer request types -module PrayerRequestType = - - /// Convert to a DU case from a single-character string - let fromCode code = + /// Convert this to a single-character code + override this.ToString() = + match this with + | CurrentRequest -> "C" + | LongTermRequest -> "L" + | Expecting -> "E" + | PraiseReport -> "P" + | Announcement -> "A" + + /// Create a PrayerRequestType from a single-character code + static member Parse code = match code with | "C" -> CurrentRequest | "L" -> LongTermRequest | "E" -> Expecting | "P" -> PraiseReport | "A" -> Announcement - | _ -> invalidArg "code" $"Unknown code {code}" - - /// Convert this DU case to a single-character string - let toCode = - function - | CurrentRequest -> "C" - | LongTermRequest -> "L" - | Expecting -> "E" - | PraiseReport -> "P" - | Announcement -> "A" + | _ -> invalidArg "code" $"Unknown code {code}" /// How requests should be sorted @@ -114,18 +113,18 @@ type RequestSort = /// Sort by requestor/subject, then by date | SortByRequestor -/// Functions to support request sorts -module RequestSort = - - /// Convert to a DU case from a single-character string - let fromCode code = + /// Convert this to a single-character code + override this.ToString() = + match this with + | SortByDate -> "D" + | SortByRequestor -> "R" + + /// Create a RequestSort from a single-character code + static member Parse code = match code with | "D" -> SortByDate | "R" -> SortByRequestor - | _ -> invalidArg "code" $"Unknown code {code}" - - /// Convert this DU case to a single-character string - let toCode = function SortByDate -> "D" | SortByRequestor -> "R" + | _ -> invalidArg "code" $"Unknown code {code}" open System @@ -133,33 +132,45 @@ open System /// PK type for the Church entity type ChurchId = | ChurchId of Guid -with + /// The GUID value of the church ID - member this.Value = this |> function ChurchId guid -> guid + member this.Value = + this + |> function + | ChurchId guid -> guid /// PK type for the Member entity type MemberId = | MemberId of Guid -with + /// The GUID value of the member ID - member this.Value = this |> function MemberId guid -> guid + member this.Value = + this + |> function + | MemberId guid -> guid /// PK type for the PrayerRequest entity type PrayerRequestId = | PrayerRequestId of Guid -with + /// The GUID value of the prayer request ID - member this.Value = this |> function PrayerRequestId guid -> guid + member this.Value = + this + |> function + | PrayerRequestId guid -> guid /// PK type for the SmallGroup entity type SmallGroupId = | SmallGroupId of Guid -with + /// The GUID value of the small group ID - member this.Value = this |> function SmallGroupId guid -> guid + member this.Value = + this + |> function + | SmallGroupId guid -> guid /// PK type for the TimeZone entity @@ -167,51 +178,58 @@ type TimeZoneId = TimeZoneId of string /// Functions to support time zone IDs module TimeZoneId = - + /// Convert a time zone ID to its string value - let toString = function TimeZoneId it -> it + let toString = + function + | TimeZoneId it -> it /// PK type for the User entity type UserId = | UserId of Guid -with + /// The GUID value of the user ID - member this.Value = this |> function UserId guid -> guid + member this.Value = + this + |> function + | UserId guid -> guid (*-- SPECIFIC VIEW TYPES --*) /// Statistics for churches [] type ChurchStats = - { /// The number of small groups in the church - SmallGroups : int - + { + /// The number of small groups in the church + SmallGroups: int + /// The number of prayer requests in the church - PrayerRequests : int - + PrayerRequests: int + /// The number of users who can access small groups in the church - Users : int + Users: int } /// Information needed to display the public/protected request list and small group maintenance pages [] type SmallGroupInfo = - { /// The ID of the small group - Id : string - + { + /// The ID of the small group + Id: string + /// The name of the small group - Name : string - + Name: string + /// The name of the church to which the small group belongs - ChurchName : string - + ChurchName: string + /// The ID of the time zone for the small group - TimeZoneId : TimeZoneId - + TimeZoneId: TimeZoneId + /// Whether the small group has a publicly-available request list - IsPublic : bool + IsPublic: bool } (*-- ENTITIES --*) @@ -221,195 +239,196 @@ open NodaTime /// This represents a church [] type Church = - { /// The ID of this church - Id : ChurchId - + { + /// The ID of this church + Id: ChurchId + /// The name of the church - Name : string - + Name: string + /// The city where the church is - City : string - + City: string + /// The 2-letter state or province code for the church's location - State : string - + State: string + /// Does this church have an active interface with Virtual Prayer Space? - HasVpsInterface : bool - + HasVpsInterface: bool + /// The address for the interface - InterfaceAddress : string option + InterfaceAddress: string option } /// Functions to support churches module Church = - + /// An empty church // aww... how sad :( let empty = - { Id = ChurchId Guid.Empty - Name = "" - City = "" - State = "" - HasVpsInterface = false - InterfaceAddress = None - } - + { Id = ChurchId Guid.Empty + Name = "" + City = "" + State = "" + HasVpsInterface = false + InterfaceAddress = None } + /// Preferences for the form and format of the prayer request list [] type ListPreferences = - { /// The Id of the small group to which these preferences belong - SmallGroupId : SmallGroupId - + { + /// The Id of the small group to which these preferences belong + SmallGroupId: SmallGroupId + /// The days after which regular requests expire - DaysToExpire : int - + DaysToExpire: int + /// The number of days a new or updated request is considered new - DaysToKeepNew : int - + DaysToKeepNew: int + /// The number of weeks after which long-term requests are flagged for follow-up - LongTermUpdateWeeks : int - + LongTermUpdateWeeks: int + /// The name from which e-mails are sent - EmailFromName : string - + EmailFromName: string + /// The e-mail address from which e-mails are sent - EmailFromAddress : string - + EmailFromAddress: string + /// The fonts to use in generating the list of prayer requests - Fonts : string - + Fonts: string + /// The color for the prayer request list headings - HeadingColor : string - + HeadingColor: string + /// The color for the lines offsetting the prayer request list headings - LineColor : string - + LineColor: string + /// The font size for the headings on the prayer request list - HeadingFontSize : int - + HeadingFontSize: int + /// The font size for the text on the prayer request list - TextFontSize : int - + TextFontSize: int + /// The order in which the prayer requests are sorted - RequestSort : RequestSort - + RequestSort: RequestSort + /// The password used for "small group login" (view-only request list) - GroupPassword : string - + GroupPassword: string + /// The default e-mail type for this class - DefaultEmailType : EmailFormat - + DefaultEmailType: EmailFormat + /// Whether this class makes its request list public - IsPublic : bool - + IsPublic: bool + /// The time zone which this class uses (use tzdata names) - TimeZoneId : TimeZoneId - + TimeZoneId: TimeZoneId + /// The number of requests displayed per page - PageSize : int - + PageSize: int + /// How the as-of date should be automatically displayed - AsOfDateDisplay : AsOfDateDisplay + AsOfDateDisplay: AsOfDateDisplay } -with - + /// The list of fonts to use when displaying request lists (converts "native" to native font stack) member this.FontStack = if this.Fonts = "native" then """system-ui,-apple-system,"Segoe UI",Roboto,Ubuntu,"Liberation Sans",Cantarell,"Helvetica Neue",sans-serif""" - else this.Fonts + else + this.Fonts /// Functions to support list preferences module ListPreferences = - + /// A set of preferences with their default values let empty = - { SmallGroupId = SmallGroupId Guid.Empty - DaysToExpire = 14 - DaysToKeepNew = 7 - LongTermUpdateWeeks = 4 - EmailFromName = "PrayerTracker" - EmailFromAddress = "prayer@bitbadger.solutions" - Fonts = "native" - HeadingColor = "maroon" - LineColor = "navy" - HeadingFontSize = 16 - TextFontSize = 12 - RequestSort = SortByDate - GroupPassword = "" - DefaultEmailType = HtmlFormat - IsPublic = false - TimeZoneId = TimeZoneId "America/Denver" - PageSize = 100 - AsOfDateDisplay = NoDisplay - } + { SmallGroupId = SmallGroupId Guid.Empty + DaysToExpire = 14 + DaysToKeepNew = 7 + LongTermUpdateWeeks = 4 + EmailFromName = "PrayerTracker" + EmailFromAddress = "prayer@bitbadger.solutions" + Fonts = "native" + HeadingColor = "maroon" + LineColor = "navy" + HeadingFontSize = 16 + TextFontSize = 12 + RequestSort = SortByDate + GroupPassword = "" + DefaultEmailType = HtmlFormat + IsPublic = false + TimeZoneId = TimeZoneId "America/Denver" + PageSize = 100 + AsOfDateDisplay = NoDisplay } /// A member of a small group [] type Member = - { /// The ID of the small group member - Id : MemberId - + { + /// The ID of the small group member + Id: MemberId + /// The Id of the small group to which this member belongs - SmallGroupId : SmallGroupId - + SmallGroupId: SmallGroupId + /// The name of the member - Name : string - + Name: string + /// The e-mail address for the member - Email : string - + Email: string + /// The type of e-mail preferred by this member - Format : EmailFormat option + Format: EmailFormat option } /// Functions to support small group members module Member = - + /// An empty member let empty = - { Id = MemberId Guid.Empty - SmallGroupId = SmallGroupId Guid.Empty - Name = "" - Email = "" - Format = None - } + { Id = MemberId Guid.Empty + SmallGroupId = SmallGroupId Guid.Empty + Name = "" + Email = "" + Format = None } /// This represents a single prayer request [] type PrayerRequest = - { /// The ID of this request - Id : PrayerRequestId - + { + /// The ID of this request + Id: PrayerRequestId + /// The type of the request - RequestType : PrayerRequestType - + RequestType: PrayerRequestType + /// The ID of 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 : Instant - + EnteredDate: Instant + /// The date/time this request was last updated - UpdatedDate : Instant - + UpdatedDate: Instant + /// The name of the requestor or subject, or title of announcement - Requestor : string option - + Requestor: string option + /// The text of the request - Text : string - + Text: string + /// Whether the chaplain should be notified for this request - NotifyChaplain : bool - + NotifyChaplain: bool + /// Is this request expired? - Expiration : Expiration + Expiration: Expiration } // functions are below small group functions @@ -417,141 +436,147 @@ type PrayerRequest = /// This represents a small group (Sunday School class, Bible study group, etc.) [] type SmallGroup = - { /// The ID of this small group - Id : SmallGroupId - + { + /// The ID of this small group + Id: SmallGroupId + /// The church to which this group belongs - ChurchId : ChurchId - + ChurchId: ChurchId + /// The name of the group - Name : string - + Name: string + /// The preferences for the request list - Preferences : ListPreferences + Preferences: ListPreferences } /// Functions to support small groups module SmallGroup = - + /// An empty small group let empty = - { Id = SmallGroupId Guid.Empty - ChurchId = ChurchId Guid.Empty - Name = "" - Preferences = ListPreferences.empty - } + { Id = SmallGroupId Guid.Empty + ChurchId = ChurchId Guid.Empty + Name = "" + Preferences = ListPreferences.empty } /// The DateTimeZone for the time zone ID for this small group let timeZone group = let tzId = TimeZoneId.toString group.Preferences.TimeZoneId - if DateTimeZoneProviders.Tzdb.Ids.Contains tzId then DateTimeZoneProviders.Tzdb[tzId] - else DateTimeZone.Utc - + + if DateTimeZoneProviders.Tzdb.Ids.Contains tzId then + DateTimeZoneProviders.Tzdb[tzId] + else + DateTimeZone.Utc + /// Get the local date/time for this group - let localTimeNow (clock : IClock) group = - if isNull clock then nullArg (nameof clock) + let localTimeNow (clock: IClock) group = + if isNull clock then + nullArg (nameof clock) + clock.GetCurrentInstant().InZone(timeZone group).LocalDateTime /// Get the local date for this group - let localDateNow clock group = - (localTimeNow clock group).Date + let localDateNow clock group = (localTimeNow clock group).Date /// Functions to support prayer requests module PrayerRequest = - + /// An empty request let empty = - { Id = PrayerRequestId Guid.Empty - RequestType = CurrentRequest - UserId = UserId Guid.Empty - SmallGroupId = SmallGroupId Guid.Empty - EnteredDate = Instant.MinValue - UpdatedDate = Instant.MinValue - Requestor = None - Text = "" - NotifyChaplain = false - Expiration = Automatic - } + { Id = PrayerRequestId Guid.Empty + RequestType = CurrentRequest + UserId = UserId Guid.Empty + SmallGroupId = SmallGroupId Guid.Empty + EnteredDate = Instant.MinValue + UpdatedDate = Instant.MinValue + Requestor = None + Text = "" + NotifyChaplain = false + Expiration = Automatic } /// Is this request expired? - let isExpired (asOf : LocalDate) group req = + let isExpired (asOf: LocalDate) group req = match req.Expiration, req.RequestType with | Forced, _ -> true - | Manual, _ + | Manual, _ | Automatic, LongTermRequest - | Automatic, Expecting -> false + | Automatic, Expecting -> false | Automatic, _ -> // Automatic expiration - Period.Between(req.UpdatedDate.InZone(SmallGroup.timeZone group).Date, asOf, PeriodUnits.Days).Days - >= group.Preferences.DaysToExpire + 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 = - if isExpired asOf group req then false - else asOf.PlusWeeks -group.Preferences.LongTermUpdateWeeks - >= req.UpdatedDate.InZone(SmallGroup.timeZone group).Date + if isExpired asOf group req then + false + else + asOf.PlusWeeks -group.Preferences.LongTermUpdateWeeks + >= req.UpdatedDate.InZone(SmallGroup.timeZone group).Date /// This represents a user of PrayerTracker [] type User = - { /// The ID of this user - Id : UserId - + { + /// The ID of this user + Id: UserId + /// The first name of this user - FirstName : string - + FirstName: string + /// The last name of this user - LastName : string - + LastName: string + /// The e-mail address of the user - Email : string - + Email: string + /// Whether this user is a PrayerTracker system administrator - IsAdmin : bool - + IsAdmin: bool + /// The user's hashed password - PasswordHash : string - + PasswordHash: string + /// The last time the user was seen (set whenever the user is loaded into a session) - LastSeen : Instant option + LastSeen: Instant option } -with + /// The full name of the user - member this.Name = - $"{this.FirstName} {this.LastName}" + member this.Name = $"{this.FirstName} {this.LastName}" /// Functions to support users module User = - + /// An empty user let empty = - { Id = UserId Guid.Empty - FirstName = "" - LastName = "" - Email = "" - IsAdmin = false - PasswordHash = "" - LastSeen = None - } + { Id = UserId Guid.Empty + FirstName = "" + LastName = "" + Email = "" + IsAdmin = false + PasswordHash = "" + LastSeen = None } /// Cross-reference between user and small group [] type UserSmallGroup = - { /// The Id of the user who has access to the small group - UserId : UserId - + { + /// The Id of the user who has access to the small group + UserId: UserId + /// The Id of the small group to which the user has access - SmallGroupId : SmallGroupId + SmallGroupId: SmallGroupId } /// Functions to support user/small group cross-reference module UserSmallGroup = - + /// An empty user/small group xref let empty = - { UserId = UserId Guid.Empty - SmallGroupId = SmallGroupId Guid.Empty - } + { UserId = UserId Guid.Empty + SmallGroupId = SmallGroupId Guid.Empty } diff --git a/src/PrayerTracker.Tests/Data/EntitiesTests.fs b/src/PrayerTracker.Tests/Data/EntitiesTests.fs index e9a59c4..8e8e045 100644 --- a/src/PrayerTracker.Tests/Data/EntitiesTests.fs +++ b/src/PrayerTracker.Tests/Data/EntitiesTests.fs @@ -8,28 +8,32 @@ open System [] let asOfDateDisplayTests = testList "AsOfDateDisplay" [ - test "NoDisplay code is correct" { - Expect.equal (AsOfDateDisplay.toCode NoDisplay) "N" "The code for NoDisplay should have been \"N\"" - } - test "ShortDate code is correct" { - Expect.equal (AsOfDateDisplay.toCode ShortDate) "S" "The code for ShortDate should have been \"S\"" - } - test "LongDate code is correct" { - Expect.equal (AsOfDateDisplay.toCode LongDate) "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" - } + testList "ToString" [ + test "NoDisplay code is correct" { + Expect.equal (string NoDisplay) "N" "The code for NoDisplay should have been \"N\"" + } + test "ShortDate code is correct" { + Expect.equal (string ShortDate) "S" "The code for ShortDate should have been \"S\"" + } + test "LongDate code is correct" { + Expect.equal (string LongDate) "L" "The code for LongDate should have been \"N\"" + } + ] + testList "Parse" [ + test "N should return NoDisplay" { + Expect.equal (AsOfDateDisplay.Parse "N") NoDisplay "\"N\" should have been parsed to NoDisplay" + } + test "S should return ShortDate" { + Expect.equal (AsOfDateDisplay.Parse "S") ShortDate "\"S\" should have been parsed to ShortDate" + } + test "L should return LongDate" { + Expect.equal (AsOfDateDisplay.Parse "L") LongDate "\"L\" should have been parsed to LongDate" + } + test "X should raise" { + Expect.throws (fun () -> AsOfDateDisplay.Parse "X" |> ignore) + "An unknown code should have raised an exception" + } + ] ] [] @@ -49,50 +53,58 @@ let churchTests = [] let emailFormatTests = testList "EmailFormat" [ - test "HtmlFormat code is correct" { - Expect.equal (EmailFormat.toCode HtmlFormat) "H" "The code for HtmlFormat should have been \"H\"" - } - test "PlainTextFormat code is correct" { - Expect.equal (EmailFormat.toCode PlainTextFormat) "P" "The code for PlainTextFormat should have been \"P\"" - } - test "fromCode H should return HtmlFormat" { - Expect.equal (EmailFormat.fromCode "H") HtmlFormat "\"H\" should have been converted to HtmlFormat" - } - test "fromCode P should return ShortDate" { - Expect.equal (EmailFormat.fromCode "P") PlainTextFormat - "\"P\" should have been converted to PlainTextFormat" - } - test "fromCode Z should raise" { - Expect.throws (fun () -> EmailFormat.fromCode "Z" |> ignore) - "An unknown code should have raised an exception" - } + testList "ToString" [ + test "HtmlFormat code is correct" { + Expect.equal (string HtmlFormat) "H" "The code for HtmlFormat should have been \"H\"" + } + test "PlainTextFormat code is correct" { + Expect.equal (string PlainTextFormat) "P" "The code for PlainTextFormat should have been \"P\"" + } + ] + testList "Parse" [ + test "H should return HtmlFormat" { + Expect.equal (EmailFormat.Parse "H") HtmlFormat "\"H\" should have been converted to HtmlFormat" + } + test "P should return ShortDate" { + Expect.equal (EmailFormat.Parse "P") PlainTextFormat + "\"P\" should have been converted to PlainTextFormat" + } + test "Z should raise" { + Expect.throws (fun () -> EmailFormat.Parse "Z" |> ignore) + "An unknown code should have raised an exception" + } + ] ] [] let expirationTests = testList "Expiration" [ - test "Automatic code is correct" { - Expect.equal (Expiration.toCode Automatic) "A" "The code for Automatic should have been \"A\"" - } - test "Manual code is correct" { - Expect.equal (Expiration.toCode Manual) "M" "The code for Manual should have been \"M\"" - } - test "Forced code is correct" { - Expect.equal (Expiration.toCode Forced) "F" "The code for Forced should have been \"F\"" - } - test "fromCode A should return Automatic" { - Expect.equal (Expiration.fromCode "A") Automatic "\"A\" should have been converted to Automatic" - } - test "fromCode M should return Manual" { - Expect.equal (Expiration.fromCode "M") Manual "\"M\" should have been converted to Manual" - } - test "fromCode F should return Forced" { - Expect.equal (Expiration.fromCode "F") Forced "\"F\" should have been converted to Forced" - } - test "fromCode V should raise" { - Expect.throws (fun () -> Expiration.fromCode "V" |> ignore) - "An unknown code should have raised an exception" - } + testList "ToString" [ + test "Automatic code is correct" { + Expect.equal (string Automatic) "A" "The code for Automatic should have been \"A\"" + } + test "Manual code is correct" { + Expect.equal (string Manual) "M" "The code for Manual should have been \"M\"" + } + test "Forced code is correct" { + Expect.equal (string Forced) "F" "The code for Forced should have been \"F\"" + } + ] + testList "Parse" [ + test "A should return Automatic" { + Expect.equal (Expiration.Parse "A") Automatic "\"A\" should have been converted to Automatic" + } + test "M should return Manual" { + Expect.equal (Expiration.Parse "M") Manual "\"M\" should have been converted to Manual" + } + test "F should return Forced" { + Expect.equal (Expiration.Parse "F") Forced "\"F\" should have been converted to Forced" + } + test "fromCode V should raise" { + Expect.throws (fun () -> Expiration.Parse "V" |> ignore) + "An unknown code should have raised an exception" + } + ] ] [] @@ -223,68 +235,74 @@ let prayerRequestTests = [] let prayerRequestTypeTests = testList "PrayerRequestType" [ - test "CurrentRequest code is correct" { - Expect.equal (PrayerRequestType.toCode CurrentRequest) "C" - "The code for CurrentRequest should have been \"C\"" - } - test "LongTermRequest code is correct" { - Expect.equal (PrayerRequestType.toCode LongTermRequest) "L" - "The code for LongTermRequest should have been \"L\"" - } - test "PraiseReport code is correct" { - Expect.equal (PrayerRequestType.toCode PraiseReport) "P" "The code for PraiseReport should have been \"P\"" - } - test "Expecting code is correct" { - Expect.equal (PrayerRequestType.toCode Expecting) "E" "The code for Expecting should have been \"E\"" - } - test "Announcement code is correct" { - Expect.equal (PrayerRequestType.toCode Announcement) "A" "The code for Announcement should have been \"A\"" - } - test "fromCode C should return CurrentRequest" { - Expect.equal (PrayerRequestType.fromCode "C") CurrentRequest - "\"C\" should have been converted to CurrentRequest" - } - test "fromCode L should return LongTermRequest" { - Expect.equal (PrayerRequestType.fromCode "L") LongTermRequest - "\"L\" should have been converted to LongTermRequest" - } - test "fromCode P should return PraiseReport" { - Expect.equal (PrayerRequestType.fromCode "P") PraiseReport - "\"P\" should have been converted to PraiseReport" - } - test "fromCode E should return Expecting" { - Expect.equal (PrayerRequestType.fromCode "E") Expecting "\"E\" should have been converted to Expecting" - } - test "fromCode A should return Announcement" { - Expect.equal (PrayerRequestType.fromCode "A") Announcement - "\"A\" should have been converted to Announcement" - } - test "fromCode R should raise" { - Expect.throws (fun () -> PrayerRequestType.fromCode "R" |> ignore) - "An unknown code should have raised an exception" - } + testList "ToString" [ + test "CurrentRequest code is correct" { + Expect.equal (string CurrentRequest) "C" "The code for CurrentRequest should have been \"C\"" + } + test "LongTermRequest code is correct" { + Expect.equal (string LongTermRequest) "L" "The code for LongTermRequest should have been \"L\"" + } + test "PraiseReport code is correct" { + Expect.equal (string PraiseReport) "P" "The code for PraiseReport should have been \"P\"" + } + test "Expecting code is correct" { + Expect.equal (string Expecting) "E" "The code for Expecting should have been \"E\"" + } + test "Announcement code is correct" { + Expect.equal (string Announcement) "A" "The code for Announcement should have been \"A\"" + } + ] + testList "Parse" [ + test "C should return CurrentRequest" { + Expect.equal (PrayerRequestType.Parse "C") CurrentRequest + "\"C\" should have been converted to CurrentRequest" + } + test "L should return LongTermRequest" { + Expect.equal (PrayerRequestType.Parse "L") LongTermRequest + "\"L\" should have been converted to LongTermRequest" + } + test "P should return PraiseReport" { + Expect.equal (PrayerRequestType.Parse "P") PraiseReport + "\"P\" should have been converted to PraiseReport" + } + test "E should return Expecting" { + Expect.equal (PrayerRequestType.Parse "E") Expecting "\"E\" should have been converted to Expecting" + } + test "A should return Announcement" { + Expect.equal (PrayerRequestType.Parse "A") Announcement + "\"A\" should have been converted to Announcement" + } + test "R should raise" { + Expect.throws (fun () -> PrayerRequestType.Parse "R" |> ignore) + "An unknown code should have raised an exception" + } + ] ] [] let requestSortTests = testList "RequestSort" [ - test "SortByDate code is correct" { - Expect.equal (RequestSort.toCode SortByDate) "D" "The code for SortByDate should have been \"D\"" - } - test "SortByRequestor code is correct" { - Expect.equal (RequestSort.toCode SortByRequestor) "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" - } + testList "ToString" [ + test "SortByDate code is correct" { + Expect.equal (string SortByDate) "D" "The code for SortByDate should have been \"D\"" + } + test "SortByRequestor code is correct" { + Expect.equal (string SortByRequestor) "R" "The code for SortByRequestor should have been \"R\"" + } + ] + testList "Parse" [ + test "D should return SortByDate" { + Expect.equal (RequestSort.Parse "D") SortByDate "\"D\" should have been converted to SortByDate" + } + test "R should return SortByRequestor" { + Expect.equal (RequestSort.Parse "R") SortByRequestor + "\"R\" should have been converted to SortByRequestor" + } + test "Q should raise" { + Expect.throws (fun () -> RequestSort.Parse "Q" |> ignore) + "An unknown code should have raised an exception" + } + ] ] [] diff --git a/src/PrayerTracker.Tests/UI/ViewModelsTests.fs b/src/PrayerTracker.Tests/UI/ViewModelsTests.fs index 739fa0c..03fb399 100644 --- a/src/PrayerTracker.Tests/UI/ViewModelsTests.fs +++ b/src/PrayerTracker.Tests/UI/ViewModelsTests.fs @@ -22,12 +22,9 @@ module ReferenceListTests = 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 = AsOfDateDisplay.toCode NoDisplay) - "The option for no display was not found" - Expect.exists asOf (fun (x, _) -> x = AsOfDateDisplay.toCode ShortDate) - "The option for a short date was not found" - Expect.exists asOf (fun (x, _) -> x = AsOfDateDisplay.toCode LongDate) - "The option for a full date was not found" + Expect.exists asOf (fun (x, _) -> x = string NoDisplay) "The option for no display was not found" + Expect.exists asOf (fun (x, _) -> x = string ShortDate) "The option for a short date was not found" + Expect.exists asOf (fun (x, _) -> x = string LongDate) "The option for a full date was not found" } ] @@ -41,9 +38,9 @@ module ReferenceListTests = Expect.equal (fst top) "" "The default option should have been blank" Expect.equal (snd top).Value "Group Default (HTML Format)" "The default option label was incorrect" let nxt = typs |> Seq.skip 1 |> Seq.head - Expect.equal (fst nxt) (EmailFormat.toCode HtmlFormat) "The 2nd option should have been HTML" + Expect.equal (fst nxt) (string HtmlFormat) "The 2nd option should have been HTML" let lst = typs |> Seq.last - Expect.equal (fst lst) (EmailFormat.toCode PlainTextFormat) "The 3rd option should have been plain text" + Expect.equal (fst lst) (string PlainTextFormat) "The 3rd option should have been plain text" } ] @@ -53,19 +50,19 @@ module ReferenceListTests = test "excludes immediate expiration if not required" { let exps = ReferenceList.expirationList _s false Expect.hasCountOf exps 2u countAll "There should have been 2 expiration types returned" - Expect.exists exps (fun (exp, _) -> exp = Expiration.toCode Automatic) + Expect.exists exps (fun (exp, _) -> exp = string Automatic) "The option for automatic expiration was not found" - Expect.exists exps (fun (exp, _) -> exp = Expiration.toCode Manual) + Expect.exists exps (fun (exp, _) -> exp = string Manual) "The option for manual expiration was not found" } test "includes immediate expiration if required" { let exps = ReferenceList.expirationList _s true Expect.hasCountOf exps 3u countAll "There should have been 3 expiration types returned" - Expect.exists exps (fun (exp, _) -> exp = Expiration.toCode Automatic) + Expect.exists exps (fun (exp, _) -> exp = string Automatic) "The option for automatic expiration was not found" - Expect.exists exps (fun (exp, _) -> exp = Expiration.toCode Manual) + Expect.exists exps (fun (exp, _) -> exp = string Manual) "The option for manual expiration was not found" - Expect.exists exps (fun (exp, _) -> exp = Expiration.toCode Forced) + Expect.exists exps (fun (exp, _) -> exp = string Forced) "The option for immediate expiration was not found" } ] @@ -240,7 +237,7 @@ let editMemberTests = } test "fromMember populates with specific format" { let edit = EditMember.fromMember { Member.empty with Format = Some HtmlFormat } - Expect.equal edit.Format (EmailFormat.toCode HtmlFormat) "The e-mail format was not filled correctly" + Expect.equal edit.Format (string HtmlFormat) "The e-mail format was not filled correctly" } test "empty is as expected" { let edit = EditMember.empty @@ -268,11 +265,10 @@ let editPreferencesTests = 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 (RequestSort.toCode prefs.RequestSort) - "The request sort was not filled correctly" + Expect.equal edit.RequestSort (string prefs.RequestSort) "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 (EmailFormat.toCode prefs.DefaultEmailType) + Expect.equal edit.DefaultEmailType (string prefs.DefaultEmailType) "The default e-mail type was not filled correctly" Expect.equal edit.LineColorType "Name" "The heading line color type was not derived correctly" Expect.equal edit.LineColor prefs.LineColor "The heading line color was not filled correctly" @@ -288,8 +284,7 @@ let editPreferencesTests = Expect.equal edit.Visibility GroupVisibility.PrivateList "The list visibility was not derived correctly" Expect.equal edit.PageSize prefs.PageSize "The page size was not filled correctly" - Expect.equal edit.AsOfDate (AsOfDateDisplay.toCode prefs.AsOfDateDisplay) - "The as-of date display was not filled correctly" + Expect.equal edit.AsOfDate (string prefs.AsOfDateDisplay) "The as-of date display was not filled correctly" } test "fromPreferences succeeds for RGB line color and password-protected list" { let prefs = { ListPreferences.empty with LineColor = "#ff0000"; GroupPassword = "pw" } @@ -326,13 +321,11 @@ let editRequestTests = test "empty is as expected" { let mt = EditRequest.empty Expect.equal mt.RequestId emptyGuid "The request ID should be an empty GUID" - Expect.equal mt.RequestType (PrayerRequestType.toCode CurrentRequest) - "The request type should have been \"Current\"" + Expect.equal mt.RequestType (string CurrentRequest) "The request type should have been \"Current\"" Expect.isNone mt.EnteredDate "The entered date should have been None" Expect.isNone mt.SkipDateUpdate """The "skip date update" flag should have been None""" Expect.isNone mt.Requestor "The requestor should have been None" - Expect.equal mt.Expiration (Expiration.toCode Automatic) - """The expiration should have been "A" (Automatic)""" + Expect.equal mt.Expiration (string Automatic) """The expiration should have been "A" (Automatic)""" Expect.equal mt.Text "" "The text should have been blank" } test "fromRequest succeeds" { @@ -346,10 +339,9 @@ let editRequestTests = } let edit = EditRequest.fromRequest req Expect.equal edit.RequestId (shortGuid req.Id.Value) "The request ID was not filled correctly" - Expect.equal edit.RequestType (PrayerRequestType.toCode req.RequestType) - "The request type was not filled correctly" + Expect.equal edit.RequestType (string req.RequestType) "The request type was not filled correctly" Expect.equal edit.Requestor req.Requestor "The requestor was not filled correctly" - Expect.equal edit.Expiration (Expiration.toCode Manual) "The expiration was not filled correctly" + Expect.equal edit.Expiration (string Manual) "The expiration was not filled correctly" Expect.equal edit.Text req.Text "The text was not filled correctly" } test "isNew works for a new request" { diff --git a/src/PrayerTracker.UI/PrayerRequest.fs b/src/PrayerTracker.UI/PrayerRequest.fs index d582eae..440486e 100644 --- a/src/PrayerTracker.UI/PrayerRequest.fs +++ b/src/PrayerTracker.UI/PrayerRequest.fs @@ -29,7 +29,7 @@ let edit (model : EditRequest) today ctx viewInfo = label [ _for (nameof model.RequestType) ] [ locStr s["Request Type"] ] ReferenceList.requestTypeList s |> Seq.ofList - |> Seq.map (fun (typ, desc) -> PrayerRequestType.toCode typ, desc.Value) + |> Seq.map (fun (typ, desc) -> string typ, desc.Value) |> selectList (nameof model.RequestType) model.RequestType [ _required; _autofocus ] ] div [ _inputField ] [ diff --git a/src/PrayerTracker.UI/SmallGroup.fs b/src/PrayerTracker.UI/SmallGroup.fs index 03e2817..70d0947 100644 --- a/src/PrayerTracker.UI/SmallGroup.fs +++ b/src/PrayerTracker.UI/SmallGroup.fs @@ -54,8 +54,8 @@ let announcement isAdmin ctx viewInfo = label [ _for (nameof model.RequestType) ] [ locStr s["Request Type"] ] reqTypes |> Seq.ofList - |> Seq.map (fun (typ, desc) -> PrayerRequestType.toCode typ, desc.Value) - |> selectList (nameof model.RequestType) (PrayerRequestType.toCode Announcement) [] + |> Seq.map (fun (typ, desc) -> string typ, desc.Value) + |> selectList (nameof model.RequestType) (string Announcement) [] ] ] div [ _fieldRow ] [ submit [] "send" s["Send Announcement"] ] @@ -273,7 +273,7 @@ let members (members : Member list) (emailTypes : Map) div [ _class "cell" ] [ str mbr.Name ] div [ _class "cell" ] [ str mbr.Email ] div [ _class "cell" ] [ - locStr emailTypes[defaultArg (mbr.Format |> Option.map EmailFormat.toCode) ""] + locStr emailTypes[defaultArg (mbr.Format |> Option.map string) ""] ] ] ] diff --git a/src/PrayerTracker.UI/ViewModels.fs b/src/PrayerTracker.UI/ViewModels.fs index 05008a5..e847727 100644 --- a/src/PrayerTracker.UI/ViewModels.fs +++ b/src/PrayerTracker.UI/ViewModels.fs @@ -11,9 +11,9 @@ module ReferenceList = /// A localized list of the AsOfDateDisplay DU cases let asOfDateList (s: IStringLocalizer) = [ - AsOfDateDisplay.toCode NoDisplay, s["Do not display the “as of” date"] - AsOfDateDisplay.toCode ShortDate, s["Display a short “as of” date"] - AsOfDateDisplay.toCode LongDate, s["Display a full “as of” date"] + string NoDisplay, s["Do not display the “as of” date"] + string ShortDate, s["Display a short “as of” date"] + string LongDate, s["Display a full “as of” date"] ] /// A list of e-mail type options @@ -23,16 +23,15 @@ module ReferenceList = s[match def with HtmlFormat -> "HTML Format" | PlainTextFormat -> "Plain-Text Format"].Value seq { "", LocalizedString ("", $"""{s["Group Default"].Value} ({defaultType})""") - EmailFormat.toCode HtmlFormat, s["HTML Format"] - EmailFormat.toCode PlainTextFormat, s["Plain-Text Format"] + string HtmlFormat, s["HTML Format"] + string PlainTextFormat, s["Plain-Text Format"] } /// A list of expiration options - let expirationList (s: IStringLocalizer) includeExpireNow = [ - Expiration.toCode Automatic, s["Expire Normally"] - Expiration.toCode Manual, s["Request Never Expires"] - if includeExpireNow then Expiration.toCode Forced, s["Expire Immediately"] - ] + let expirationList (s: IStringLocalizer) includeExpireNow = + [ string Automatic, s["Expire Normally"] + string Manual, s["Request Never Expires"] + if includeExpireNow then string Forced, s["Expire Immediately"] ] /// A list of request types let requestTypeList (s: IStringLocalizer) = [ @@ -326,7 +325,7 @@ module EditMember = { MemberId = shortGuid mbr.Id.Value Name = mbr.Name Email = mbr.Email - Format = match mbr.Format with Some fmt -> EmailFormat.toCode fmt | None -> "" + Format = mbr.Format |> Option.map string |> Option.defaultValue "" } /// An empty instance @@ -413,10 +412,10 @@ with DaysToExpire = this.ExpireDays DaysToKeepNew = this.DaysToKeepNew LongTermUpdateWeeks = this.LongTermUpdateWeeks - RequestSort = RequestSort.fromCode this.RequestSort + RequestSort = RequestSort.Parse this.RequestSort EmailFromName = this.EmailFromName EmailFromAddress = this.EmailFromAddress - DefaultEmailType = EmailFormat.fromCode this.DefaultEmailType + DefaultEmailType = EmailFormat.Parse this.DefaultEmailType LineColor = this.LineColor HeadingColor = this.HeadingColor Fonts = if this.IsNative || Option.isNone this.Fonts then "native" else this.Fonts.Value @@ -426,7 +425,7 @@ with IsPublic = isPublic GroupPassword = grpPw PageSize = this.PageSize - AsOfDateDisplay = AsOfDateDisplay.fromCode this.AsOfDate + AsOfDateDisplay = AsOfDateDisplay.Parse this.AsOfDate } /// Support for the EditPreferences type @@ -437,10 +436,10 @@ module EditPreferences = { ExpireDays = prefs.DaysToExpire DaysToKeepNew = prefs.DaysToKeepNew LongTermUpdateWeeks = prefs.LongTermUpdateWeeks - RequestSort = RequestSort.toCode prefs.RequestSort + RequestSort = string prefs.RequestSort EmailFromName = prefs.EmailFromName EmailFromAddress = prefs.EmailFromAddress - DefaultEmailType = EmailFormat.toCode prefs.DefaultEmailType + DefaultEmailType = string prefs.DefaultEmailType LineColorType = setType prefs.LineColor LineColor = prefs.LineColor HeadingColorType = setType prefs.HeadingColor @@ -452,7 +451,7 @@ module EditPreferences = TimeZone = TimeZoneId.toString prefs.TimeZoneId GroupPassword = Some prefs.GroupPassword PageSize = prefs.PageSize - AsOfDate = AsOfDateDisplay.toCode prefs.AsOfDateDisplay + AsOfDate = string prefs.AsOfDateDisplay Visibility = if prefs.IsPublic then GroupVisibility.PublicList elif prefs.GroupPassword = "" then GroupVisibility.PrivateList @@ -495,11 +494,11 @@ module EditRequest = /// An empty instance to use for new requests let empty = { RequestId = emptyGuid - RequestType = PrayerRequestType.toCode CurrentRequest + RequestType = string CurrentRequest EnteredDate = None SkipDateUpdate = None Requestor = None - Expiration = Expiration.toCode Automatic + Expiration = string Automatic Text = "" } @@ -507,9 +506,9 @@ module EditRequest = let fromRequest (req: PrayerRequest) = { empty with RequestId = shortGuid req.Id.Value - RequestType = PrayerRequestType.toCode req.RequestType + RequestType = string req.RequestType Requestor = req.Requestor - Expiration = Expiration.toCode req.Expiration + Expiration = string req.Expiration Text = req.Text } diff --git a/src/PrayerTracker/PrayerRequest.fs b/src/PrayerTracker/PrayerRequest.fs index 762a348..d48c764 100644 --- a/src/PrayerTracker/PrayerRequest.fs +++ b/src/PrayerTracker/PrayerRequest.fs @@ -238,10 +238,10 @@ let save : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> fun next ct let now = SmallGroup.localDateNow ctx.Clock group let updated = { pr with - RequestType = PrayerRequestType.fromCode model.RequestType + RequestType = PrayerRequestType.Parse model.RequestType Requestor = match model.Requestor with Some x when x.Trim() = "" -> None | x -> x Text = ckEditorToText model.Text - Expiration = Expiration.fromCode model.Expiration + Expiration = Expiration.Parse model.Expiration } |> function | it when model.IsNew -> diff --git a/src/PrayerTracker/SmallGroup.fs b/src/PrayerTracker/SmallGroup.fs index 143df7a..ed365c6 100644 --- a/src/PrayerTracker/SmallGroup.fs +++ b/src/PrayerTracker/SmallGroup.fs @@ -210,7 +210,7 @@ let saveMember : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> fun n { mbr with Name = model.Name Email = model.Email - Format = String.noneIfBlank model.Format |> Option.map EmailFormat.fromCode } + Format = String.noneIfBlank model.Format |> Option.map EmailFormat.Parse } let act = ctx.Strings[if model.IsNew then "Added" else "Updated"].Value.ToLower() addInfo ctx ctx.Strings["Successfully {0} group member", act] return! redirectTo false "/small-group/members" next ctx @@ -288,7 +288,7 @@ let sendAnnouncement : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> Id = (Guid.NewGuid >> PrayerRequestId) () SmallGroupId = group.Id UserId = usr.Id - RequestType = (Option.get >> PrayerRequestType.fromCode) model.RequestType + RequestType = (Option.get >> PrayerRequestType.Parse) model.RequestType Text = requestText EnteredDate = now.Date.AtStartOfDayInZone(zone).ToInstant() UpdatedDate = now.InZoneLeniently(zone).ToInstant() }