Version 8 #43
| @ -78,13 +78,13 @@ type AppDbContext (options : DbContextOptions<AppDbContext>) = | ||||
| 
 | ||||
|         modelBuilder.HasDefaultSchema "pt" |> ignore | ||||
| 
 | ||||
|         [ Church.configureEF | ||||
|           ListPreferences.configureEF | ||||
|           Member.configureEF | ||||
|           PrayerRequest.configureEF | ||||
|           SmallGroup.configureEF | ||||
|           TimeZone.configureEF | ||||
|           User.configureEF | ||||
|           UserSmallGroup.configureEF | ||||
|         [ Church.ConfigureEF | ||||
|           ListPreferences.ConfigureEF | ||||
|           Member.ConfigureEF | ||||
|           PrayerRequest.ConfigureEF | ||||
|           SmallGroup.ConfigureEF | ||||
|           TimeZone.ConfigureEF | ||||
|           User.ConfigureEF | ||||
|           UserSmallGroup.ConfigureEF | ||||
|           ] | ||||
|         |> List.iter (fun x -> x modelBuilder) | ||||
|  | ||||
| @ -91,7 +91,7 @@ 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 pageNbr = backgroundTask { | ||||
|         let theDate = match listDate with Some dt -> dt | _ -> grp.localDateNow clock | ||||
|         let theDate = match listDate with Some dt -> dt | _ -> grp.LocalDateNow clock | ||||
|         let query = | ||||
|             this.PrayerRequests.Where(fun req -> req.SmallGroupId = grp.Id) | ||||
|             |> function | ||||
| @ -120,15 +120,15 @@ type AppDbContext with | ||||
|         return! this.PrayerRequests.CountAsync (fun pr -> pr.SmallGroup.ChurchId = churchId) | ||||
|     } | ||||
| 
 | ||||
|     /// Get all (or active) requests for a small group as of now or the specified date | ||||
|     /// Search requests for a small group using the given case-insensitive search term | ||||
|     member this.SearchRequestsForSmallGroup (grp : SmallGroup) (searchTerm : string) pageNbr = backgroundTask { | ||||
|         let sql = """ | ||||
|             SELECT * FROM pt."PrayerRequest" WHERE "SmallGroupId" = {0} AND "Text" ILIKE {1} | ||||
|             SELECT * FROM pt.prayer_request WHERE small_group_id = {0} AND request_text ILIKE {1} | ||||
|         UNION | ||||
|             SELECT * FROM pt."PrayerRequest" WHERE "SmallGroupId" = {0} AND COALESCE("Requestor", '') ILIKE {1}""" | ||||
|             SELECT * FROM pt.prayer_request WHERE small_group_id = {0} AND COALESCE(requestor, '') ILIKE {1}""" | ||||
|         let like  = sprintf "%%%s%%" | ||||
|         let query = | ||||
|             this.PrayerRequests.FromSqlRaw(sql, grp.Id, like searchTerm) | ||||
|             this.PrayerRequests.FromSqlRaw (sql, grp.Id.Value, like searchTerm) | ||||
|             |> reqSort grp.Preferences.RequestSort | ||||
|             |> paginate pageNbr grp.Preferences.PageSize | ||||
|         let! reqs = query.ToListAsync () | ||||
| @ -255,7 +255,7 @@ type AppDbContext with | ||||
|     /// Get all PrayerTracker users as members (used to send e-mails) | ||||
|     member this.AllUsersAsMembers () = backgroundTask { | ||||
|         let! users = this.AllUsers () | ||||
|         return users |> List.map (fun u -> { Member.empty with Email = u.Email; Name = u.fullName }) | ||||
|         return users |> List.map (fun u -> { Member.empty with Email = u.Email; Name = u.Name }) | ||||
|     } | ||||
| 
 | ||||
|     /// Find a user based on their credentials | ||||
|  | ||||
| @ -394,8 +394,8 @@ type [<CLIMutable; NoComparison; NoEquality>] Church = | ||||
|         /// The 2-letter state or province code for the church's location | ||||
|         State : string | ||||
|          | ||||
|         /// Does this church have an active interface with Virtual Prayer Room? | ||||
|         HasInterface : bool | ||||
|         /// Does this church have an active interface with Virtual Prayer Space? | ||||
|         HasVpsInterface : bool | ||||
|          | ||||
|         /// The address for the interface | ||||
|         InterfaceAddress : string option | ||||
| @ -411,24 +411,27 @@ with | ||||
|             Name             = "" | ||||
|             City             = "" | ||||
|             State            = "" | ||||
|             HasInterface     = false | ||||
|             HasVpsInterface  = false | ||||
|             InterfaceAddress = None | ||||
|             SmallGroups      = List<SmallGroup> () | ||||
|         } | ||||
|      | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<Church> (fun m -> | ||||
|             m.ToTable "Church" |> ignore | ||||
|             m.Property(fun e -> e.Id).HasColumnName "ChurchId" |> ignore | ||||
|             m.Property(fun e -> e.Name).HasColumnName("Name").IsRequired () |> ignore | ||||
|             m.Property(fun e -> e.City).HasColumnName("City").IsRequired () |> ignore | ||||
|             m.Property(fun e -> e.State).HasColumnName("ST").IsRequired().HasMaxLength 2 |> ignore | ||||
|             m.Property(fun e -> e.HasInterface).HasColumnName "HasVirtualPrayerRoomInterface" |> ignore | ||||
|             m.Property(fun e -> e.InterfaceAddress).HasColumnName "InterfaceAddress" |> ignore) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<Church> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "church" | ||||
|                 it.Property(fun c -> c.Id).HasColumnName "id" | ||||
|                 it.Property(fun c -> c.Name).HasColumnName("church_name").IsRequired () | ||||
|                 it.Property(fun c -> c.City).HasColumnName("city").IsRequired () | ||||
|                 it.Property(fun c -> c.State).HasColumnName("state").IsRequired().HasMaxLength 2 | ||||
|                 it.Property(fun c -> c.HasVpsInterface).HasColumnName "has_vps_interface" | ||||
|                 it.Property(fun c -> c.InterfaceAddress).HasColumnName "interface_address" | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<Church>).FindProperty("Id").SetValueConverter(Converters.ChurchIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<Church>).FindProperty("InterfaceAddress") | ||||
|         mb.Model.FindEntityType(typeof<Church>).FindProperty(nameof Church.empty.Id) | ||||
|             .SetValueConverter(Converters.ChurchIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<Church>).FindProperty(nameof Church.empty.InterfaceAddress) | ||||
|             .SetValueConverter(OptionConverter<string> ()) | ||||
| 
 | ||||
| 
 | ||||
| @ -517,108 +520,50 @@ with | ||||
|         } | ||||
|      | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<ListPreferences> (fun m -> | ||||
|             m.ToTable "ListPreference" |> ignore | ||||
|             m.HasKey (fun e -> e.SmallGroupId :> obj) |> ignore | ||||
|             m.Property(fun e -> e.SmallGroupId).HasColumnName "SmallGroupId" |> ignore | ||||
|             m.Property(fun e -> e.DaysToKeepNew) | ||||
|                 .HasColumnName("DaysToKeepNew") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue 7 | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.DaysToExpire) | ||||
|                 .HasColumnName("DaysToExpire") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue 14 | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.LongTermUpdateWeeks) | ||||
|                 .HasColumnName("LongTermUpdateWeeks") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue 4 | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.EmailFromName) | ||||
|                 .HasColumnName("EmailFromName") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue "PrayerTracker" | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.EmailFromAddress) | ||||
|                 .HasColumnName("EmailFromAddress") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue "prayer@djs-consulting.com" | ||||
|               |> ignore | ||||
|             m.Property(fun e -> e.Fonts) | ||||
|                 .HasColumnName("ListFonts") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue "Century Gothic,Tahoma,Luxi Sans,sans-serif" | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.HeadingColor) | ||||
|                 .HasColumnName("HeadingColor") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue "maroon" | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.LineColor) | ||||
|                 .HasColumnName("LineColor") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue "navy" | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.HeadingFontSize) | ||||
|                 .HasColumnName("HeadingFontSize") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue 16 | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.TextFontSize) | ||||
|                 .HasColumnName("TextFontSize") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue 12 | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.RequestSort) | ||||
|                 .HasColumnName("RequestSort") | ||||
|                 .IsRequired() | ||||
|                 .HasMaxLength(1) | ||||
|                 .HasDefaultValue SortByDate | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.GroupPassword) | ||||
|                 .HasColumnName("GroupPassword") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue "" | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.DefaultEmailType) | ||||
|                 .HasColumnName("DefaultEmailType") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue HtmlFormat | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.IsPublic) | ||||
|                 .HasColumnName("IsPublic") | ||||
|                 .IsRequired() | ||||
|                 .HasDefaultValue false | ||||
|             |> ignore | ||||
|             m.Property(fun e -> e.TimeZoneId) | ||||
|                 .HasColumnName("TimeZoneId") | ||||
|                 .IsRequired() | ||||
|                 .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) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<ListPreferences> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "list_preference" | ||||
|                 it.HasKey (fun lp -> lp.SmallGroupId :> obj) | ||||
|                 it.Property(fun lp -> lp.SmallGroupId).HasColumnName "small_group_id" | ||||
|                 it.Property(fun lp -> lp.DaysToKeepNew).HasColumnName("days_to_keep_new").IsRequired().HasDefaultValue 7 | ||||
|                 it.Property(fun lp -> lp.DaysToExpire).HasColumnName("days_to_expire").IsRequired().HasDefaultValue 14 | ||||
|                 it.Property(fun lp -> lp.LongTermUpdateWeeks).HasColumnName("long_term_update_weeks").IsRequired() | ||||
|                     .HasDefaultValue 4 | ||||
|                 it.Property(fun lp -> lp.EmailFromName).HasColumnName("email_from_name").IsRequired() | ||||
|                     .HasDefaultValue "PrayerTracker" | ||||
|                 it.Property(fun lp -> lp.EmailFromAddress).HasColumnName("email_from_address").IsRequired() | ||||
|                     .HasDefaultValue "prayer@djs-consulting.com" | ||||
|                 it.Property(fun lp -> lp.Fonts).HasColumnName("fonts").IsRequired() | ||||
|                     .HasDefaultValue "Century Gothic,Tahoma,Luxi Sans,sans-serif" | ||||
|                 it.Property(fun lp -> lp.HeadingColor).HasColumnName("heading_color").IsRequired() | ||||
|                     .HasDefaultValue "maroon" | ||||
|                 it.Property(fun lp -> lp.LineColor).HasColumnName("line_color").IsRequired().HasDefaultValue "navy" | ||||
|                 it.Property(fun lp -> lp.HeadingFontSize).HasColumnName("heading_font_size").IsRequired() | ||||
|                     .HasDefaultValue 16 | ||||
|                 it.Property(fun lp -> lp.TextFontSize).HasColumnName("text_font_size").IsRequired().HasDefaultValue 12 | ||||
|                 it.Property(fun lp -> lp.RequestSort).HasColumnName("request_sort").IsRequired().HasMaxLength(1) | ||||
|                     .HasDefaultValue SortByDate | ||||
|                 it.Property(fun lp -> lp.GroupPassword).HasColumnName("group_password").IsRequired().HasDefaultValue "" | ||||
|                 it.Property(fun lp -> lp.DefaultEmailType).HasColumnName("default_email_type").IsRequired() | ||||
|                     .HasDefaultValue HtmlFormat | ||||
|                 it.Property(fun lp -> lp.IsPublic).HasColumnName("is_public").IsRequired().HasDefaultValue false | ||||
|                 it.Property(fun lp -> lp.TimeZoneId).HasColumnName("time_zone_id").IsRequired() | ||||
|                     .HasDefaultValue (TimeZoneId "America/Denver") | ||||
|                 it.Property(fun lp -> lp.PageSize).HasColumnName("page_size").IsRequired().HasDefaultValue 100 | ||||
|                 it.Property(fun lp -> lp.AsOfDateDisplay).HasColumnName("as_of_date_display").IsRequired() | ||||
|                     .HasMaxLength(1).HasDefaultValue NoDisplay | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("SmallGroupId") | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty(nameof ListPreferences.empty.SmallGroupId) | ||||
|             .SetValueConverter(Converters.SmallGroupIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("RequestSort") | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty(nameof ListPreferences.empty.RequestSort) | ||||
|             .SetValueConverter(Converters.RequestSortConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("DefaultEmailType") | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty(nameof ListPreferences.empty.DefaultEmailType) | ||||
|             .SetValueConverter(Converters.EmailFormatConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("TimeZoneId") | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty(nameof ListPreferences.empty.TimeZoneId) | ||||
|             .SetValueConverter(Converters.TimeZoneIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty("AsOfDateDisplay") | ||||
|         mb.Model.FindEntityType(typeof<ListPreferences>).FindProperty(nameof ListPreferences.empty.AsOfDateDisplay) | ||||
|             .SetValueConverter(Converters.AsOfDateDisplayConverter ()) | ||||
| 
 | ||||
| 
 | ||||
| @ -655,19 +600,22 @@ with | ||||
|         } | ||||
|      | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<Member> (fun m -> | ||||
|             m.ToTable "Member" |> ignore | ||||
|             m.Property(fun e -> e.Id).HasColumnName "MemberId" |> ignore | ||||
|             m.Property(fun e -> e.SmallGroupId).HasColumnName "SmallGroupId" |> ignore | ||||
|             m.Property(fun e -> e.Name).HasColumnName("MemberName").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.Email).HasColumnName("Email").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.Format).HasColumnName "Format" |> ignore) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<Member> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "member" | ||||
|                 it.Property(fun m -> m.Id).HasColumnName "id" | ||||
|                 it.Property(fun m -> m.SmallGroupId).HasColumnName("small_group_id").IsRequired () | ||||
|                 it.Property(fun m -> m.Name).HasColumnName("member_name").IsRequired () | ||||
|                 it.Property(fun m -> m.Email).HasColumnName("email").IsRequired () | ||||
|                 it.Property(fun m -> m.Format).HasColumnName "email_format" | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<Member>).FindProperty("Id").SetValueConverter(Converters.MemberIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<Member>).FindProperty("SmallGroupId") | ||||
|         mb.Model.FindEntityType(typeof<Member>).FindProperty(nameof Member.empty.Id) | ||||
|             .SetValueConverter(Converters.MemberIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<Member>).FindProperty(nameof Member.empty.SmallGroupId) | ||||
|             .SetValueConverter(Converters.SmallGroupIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<Member>).FindProperty("Format") | ||||
|         mb.Model.FindEntityType(typeof<Member>).FindProperty(nameof Member.empty.Format) | ||||
|             .SetValueConverter(Converters.EmailFormatOptionConverter ()) | ||||
| 
 | ||||
| 
 | ||||
| @ -713,63 +661,62 @@ with | ||||
|      | ||||
|     /// An empty request | ||||
|     static member empty = | ||||
|         {   Id              = PrayerRequestId Guid.Empty | ||||
|             RequestType     = CurrentRequest | ||||
|             UserId          = UserId Guid.Empty | ||||
|             SmallGroupId    = SmallGroupId Guid.Empty | ||||
|             EnteredDate     = DateTime.MinValue | ||||
|             UpdatedDate     = DateTime.MinValue | ||||
|             Requestor       = None | ||||
|             Text            = ""  | ||||
|             NotifyChaplain  = false | ||||
|             User            = User.empty | ||||
|             SmallGroup      = SmallGroup.empty | ||||
|             Expiration      = Automatic | ||||
|         {   Id             = PrayerRequestId Guid.Empty | ||||
|             RequestType    = CurrentRequest | ||||
|             UserId         = UserId Guid.Empty | ||||
|             SmallGroupId   = 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.Expiration with | ||||
|         | Forced -> true | ||||
|         | Manual -> false  | ||||
|         | Automatic -> | ||||
|             match this.RequestType with | ||||
|             | LongTermRequest | ||||
|             | Expecting -> false | ||||
|             | _ -> curr.AddDays(-(float expDays)).Date > this.UpdatedDate.Date // Automatic expiration | ||||
|     member this.IsExpired (curr : DateTime) expDays = | ||||
|         match this.Expiration, this.RequestType with | ||||
|         | Forced, _ -> true | ||||
|         | Manual, _  | ||||
|         | Automatic, LongTermRequest | ||||
|         | Automatic, Expecting  -> false | ||||
|         | Automatic, _ -> curr.AddDays(-(float expDays)).Date > this.UpdatedDate.Date // 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 | ||||
|         | false -> curr.AddDays(-(float (updWeeks * 7))).Date > this.UpdatedDate.Date | ||||
|     member this.UpdateRequired curr expDays updWeeks = | ||||
|         if this.IsExpired curr expDays then false | ||||
|         else curr.AddDays(-(float (updWeeks * 7))).Date > this.UpdatedDate.Date | ||||
| 
 | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<PrayerRequest> (fun m -> | ||||
|             m.ToTable "PrayerRequest" |> ignore | ||||
|             m.Property(fun e -> e.Id).HasColumnName "PrayerRequestId" |> ignore | ||||
|             m.Property(fun e -> e.RequestType).HasColumnName("RequestType").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.UserId).HasColumnName "UserId" |> ignore | ||||
|             m.Property(fun e -> e.SmallGroupId).HasColumnName "SmallGroupId" |> ignore | ||||
|             m.Property(fun e -> e.EnteredDate).HasColumnName "EnteredDate" |> ignore | ||||
|             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.NotifyChaplain).HasColumnName "NotifyChaplain" |> ignore | ||||
|             m.Property(fun e -> e.Expiration).HasColumnName "Expiration" |> ignore) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<PrayerRequest> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "prayer_request" | ||||
|                 it.Property(fun pr -> pr.Id).HasColumnName "id" | ||||
|                 it.Property(fun pr -> pr.RequestType).HasColumnName("request_type").IsRequired () | ||||
|                 it.Property(fun pr -> pr.UserId).HasColumnName "user_id" | ||||
|                 it.Property(fun pr -> pr.SmallGroupId).HasColumnName "small_group_id" | ||||
|                 it.Property(fun pr -> pr.EnteredDate).HasColumnName "entered_date" | ||||
|                 it.Property(fun pr -> pr.UpdatedDate).HasColumnName "updated_date" | ||||
|                 it.Property(fun pr -> pr.Requestor).HasColumnName "requestor" | ||||
|                 it.Property(fun pr -> pr.Text).HasColumnName("request_text").IsRequired () | ||||
|                 it.Property(fun pr -> pr.NotifyChaplain).HasColumnName "notify_chaplain" | ||||
|                 it.Property(fun pr -> pr.Expiration).HasColumnName "expiration" | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("Id") | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty(nameof PrayerRequest.empty.Id) | ||||
|             .SetValueConverter(Converters.PrayerRequestIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("RequestType") | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty(nameof PrayerRequest.empty.RequestType) | ||||
|             .SetValueConverter(Converters.PrayerRequestTypeConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("UserId") | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty(nameof PrayerRequest.empty.UserId) | ||||
|             .SetValueConverter(Converters.UserIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("SmallGroupId") | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty(nameof PrayerRequest.empty.SmallGroupId) | ||||
|             .SetValueConverter(Converters.SmallGroupIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("Requestor") | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty(nameof PrayerRequest.empty.Requestor) | ||||
|             .SetValueConverter(OptionConverter<string> ()) | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty("Expiration") | ||||
|         mb.Model.FindEntityType(typeof<PrayerRequest>).FindProperty(nameof PrayerRequest.empty.Expiration) | ||||
|             .SetValueConverter(Converters.ExpirationConverter ()) | ||||
| 
 | ||||
| 
 | ||||
| @ -814,8 +761,8 @@ with | ||||
|         } | ||||
| 
 | ||||
|     /// Get the local date for this group | ||||
|     member this.localTimeNow (clock : IClock) = | ||||
|         match clock with null -> nullArg "clock" | _ -> () | ||||
|     member this.LocalTimeNow (clock : IClock) = | ||||
|         if isNull clock then nullArg (nameof clock) | ||||
|         let tzId = TimeZoneId.toString this.Preferences.TimeZoneId | ||||
|         let tz = | ||||
|             if DateTimeZoneProviders.Tzdb.Ids.Contains tzId then DateTimeZoneProviders.Tzdb[tzId] | ||||
| @ -823,21 +770,26 @@ with | ||||
|         clock.GetCurrentInstant().InZone(tz).ToDateTimeUnspecified () | ||||
| 
 | ||||
|     /// Get the local date for this group | ||||
|     member this.localDateNow clock = | ||||
|         (this.localTimeNow clock).Date | ||||
|     member this.LocalDateNow clock = | ||||
|         (this.LocalTimeNow clock).Date | ||||
|      | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<SmallGroup> (fun m -> | ||||
|             m.ToTable "SmallGroup" |> ignore | ||||
|             m.Property(fun e -> e.Id).HasColumnName "SmallGroupId" |> ignore | ||||
|             m.Property(fun e -> e.ChurchId).HasColumnName "ChurchId" |> ignore | ||||
|             m.Property(fun e -> e.Name).HasColumnName("Name").IsRequired() |> ignore | ||||
|             m.HasOne(fun e -> e.Preferences) |> ignore) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<SmallGroup> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "small_group" | ||||
|                 it.Property(fun sg -> sg.Id).HasColumnName "id" | ||||
|                 it.Property(fun sg -> sg.ChurchId).HasColumnName "church_id" | ||||
|                 it.Property(fun sg -> sg.Name).HasColumnName("group_name").IsRequired () | ||||
|                 it.HasOne(fun sg -> sg.Preferences) | ||||
|                     .WithOne() | ||||
|                     .HasPrincipalKey(fun sg -> sg.Id :> obj) | ||||
|                     .HasForeignKey(fun (lp : ListPreferences) -> lp.SmallGroupId :> obj) | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<SmallGroup>).FindProperty("Id") | ||||
|         mb.Model.FindEntityType(typeof<SmallGroup>).FindProperty(nameof SmallGroup.empty.Id) | ||||
|             .SetValueConverter(Converters.SmallGroupIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<SmallGroup>).FindProperty("ChurchId") | ||||
|         mb.Model.FindEntityType(typeof<SmallGroup>).FindProperty(nameof SmallGroup.empty.ChurchId) | ||||
|             .SetValueConverter(Converters.ChurchIdConverter ()) | ||||
| 
 | ||||
| 
 | ||||
| @ -866,15 +818,17 @@ with | ||||
|         } | ||||
|      | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<TimeZone> ( fun m -> | ||||
|             m.ToTable "TimeZone" |> ignore | ||||
|             m.Property(fun e -> e.Id).HasColumnName "TimeZoneId" |> ignore | ||||
|             m.Property(fun e -> e.Description).HasColumnName("Description").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.SortOrder).HasColumnName "SortOrder" |> ignore | ||||
|             m.Property(fun e -> e.IsActive).HasColumnName "IsActive" |> ignore) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<TimeZone> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "time_zone" | ||||
|                 it.Property(fun tz -> tz.Id).HasColumnName "id" | ||||
|                 it.Property(fun tz -> tz.Description).HasColumnName("description").IsRequired () | ||||
|                 it.Property(fun tz -> tz.SortOrder).HasColumnName "sort_order" | ||||
|                 it.Property(fun tz -> tz.IsActive).HasColumnName "is_active" | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<TimeZone>).FindProperty("Id") | ||||
|         mb.Model.FindEntityType(typeof<TimeZone>).FindProperty(nameof TimeZone.empty.Id) | ||||
|             .SetValueConverter(Converters.TimeZoneIdConverter ()) | ||||
| 
 | ||||
| 
 | ||||
| @ -919,24 +873,27 @@ with | ||||
|         } | ||||
|      | ||||
|     /// The full name of the user | ||||
|     member this.fullName = | ||||
|     member this.Name = | ||||
|         $"{this.FirstName} {this.LastName}" | ||||
| 
 | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<User> (fun m -> | ||||
|             m.ToTable "User" |> ignore | ||||
|             m.Ignore(fun e -> e.fullName :> obj) |> ignore | ||||
|             m.Property(fun e -> e.Id).HasColumnName "UserId" |> ignore | ||||
|             m.Property(fun e -> e.FirstName).HasColumnName("FirstName").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.LastName).HasColumnName("LastName").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.Email).HasColumnName("EmailAddress").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.IsAdmin).HasColumnName "IsSystemAdmin" |> ignore | ||||
|             m.Property(fun e -> e.PasswordHash).HasColumnName("PasswordHash").IsRequired() |> ignore | ||||
|             m.Property(fun e -> e.Salt).HasColumnName "Salt" |> ignore) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<User> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "pt_user" | ||||
|                 it.Ignore(fun u -> u.Name :> obj) | ||||
|                 it.Property(fun u -> u.Id).HasColumnName "id" | ||||
|                 it.Property(fun u -> u.FirstName).HasColumnName("first_name").IsRequired () | ||||
|                 it.Property(fun u -> u.LastName).HasColumnName("last_name").IsRequired () | ||||
|                 it.Property(fun u -> u.Email).HasColumnName("email").IsRequired () | ||||
|                 it.Property(fun u -> u.IsAdmin).HasColumnName "is_admin" | ||||
|                 it.Property(fun u -> u.PasswordHash).HasColumnName("password_hash").IsRequired () | ||||
|                 it.Property(fun u -> u.Salt).HasColumnName "salt" | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<User>).FindProperty("Id").SetValueConverter(Converters.UserIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<User>).FindProperty("Salt") | ||||
|         mb.Model.FindEntityType(typeof<User>).FindProperty(nameof User.empty.Id) | ||||
|             .SetValueConverter(Converters.UserIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<User>).FindProperty(nameof User.empty.Salt) | ||||
|             .SetValueConverter(OptionConverter<Guid> ()) | ||||
| 
 | ||||
| 
 | ||||
| @ -965,23 +922,23 @@ with | ||||
|         } | ||||
|      | ||||
|     /// Configure EF for this entity | ||||
|     static member internal configureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<UserSmallGroup> (fun m -> | ||||
|             m.ToTable "User_SmallGroup" |> ignore | ||||
|             m.HasKey(fun e -> {| UserId = e.UserId; SmallGroupId = e.SmallGroupId |} :> obj) |> ignore | ||||
|             m.Property(fun e -> e.UserId).HasColumnName "UserId" |> ignore | ||||
|             m.Property(fun e -> e.SmallGroupId).HasColumnName "SmallGroupId" |> ignore | ||||
|             m.HasOne(fun e -> e.User) | ||||
|                 .WithMany(fun e -> e.SmallGroups :> IEnumerable<UserSmallGroup>) | ||||
|                 .HasForeignKey(fun e -> e.UserId :> obj) | ||||
|             |> ignore | ||||
|             m.HasOne(fun e -> e.SmallGroup) | ||||
|                 .WithMany(fun e -> e.Users :> IEnumerable<UserSmallGroup>) | ||||
|                 .HasForeignKey(fun e -> e.SmallGroupId :> obj) | ||||
|             |> ignore) | ||||
|     static member internal ConfigureEF (mb : ModelBuilder) = | ||||
|         mb.Entity<UserSmallGroup> (fun it -> | ||||
|             seq<obj> { | ||||
|                 it.ToTable "user_small_group" | ||||
|                 it.HasKey (nameof UserSmallGroup.empty.UserId, nameof UserSmallGroup.empty.SmallGroupId) | ||||
|                 it.Property(fun usg -> usg.UserId).HasColumnName "user_id" | ||||
|                 it.Property(fun usg -> usg.SmallGroupId).HasColumnName "small_group_id" | ||||
|                 it.HasOne(fun usg -> usg.User) | ||||
|                     .WithMany(fun u -> u.SmallGroups :> IEnumerable<UserSmallGroup>) | ||||
|                     .HasForeignKey(fun usg -> usg.UserId :> obj) | ||||
|                 it.HasOne(fun usg -> usg.SmallGroup) | ||||
|                     .WithMany(fun sg -> sg.Users :> IEnumerable<UserSmallGroup>) | ||||
|                     .HasForeignKey(fun usg -> usg.SmallGroupId :> obj) | ||||
|             } |> List.ofSeq |> ignore) | ||||
|         |> ignore | ||||
|         mb.Model.FindEntityType(typeof<UserSmallGroup>).FindProperty("UserId") | ||||
|         mb.Model.FindEntityType(typeof<UserSmallGroup>).FindProperty(nameof UserSmallGroup.empty.UserId) | ||||
|             .SetValueConverter(Converters.UserIdConverter ()) | ||||
|         mb.Model.FindEntityType(typeof<UserSmallGroup>).FindProperty("SmallGroupId") | ||||
|         mb.Model.FindEntityType(typeof<UserSmallGroup>).FindProperty(nameof UserSmallGroup.empty.SmallGroupId) | ||||
|             .SetValueConverter(Converters.SmallGroupIdConverter ()) | ||||
|          | ||||
| @ -1,514 +1,389 @@ | ||||
| namespace PrayerTracker.Migrations | ||||
| 
 | ||||
| open System | ||||
| open Microsoft.EntityFrameworkCore | ||||
| open Microsoft.EntityFrameworkCore.Infrastructure | ||||
| open Microsoft.EntityFrameworkCore.Migrations | ||||
| open Microsoft.EntityFrameworkCore.Migrations.Operations | ||||
| open Microsoft.EntityFrameworkCore.Migrations.Operations.Builders | ||||
| open Npgsql.EntityFrameworkCore.PostgreSQL.Metadata | ||||
| open PrayerTracker | ||||
| open PrayerTracker.Entities | ||||
| open System | ||||
| 
 | ||||
| // fsharplint:disable RecordFieldNames | ||||
| 
 | ||||
| type ChurchTable = | ||||
|   { churchId         : OperationBuilder<AddColumnOperation> | ||||
|     city             : OperationBuilder<AddColumnOperation> | ||||
|     hasInterface     : OperationBuilder<AddColumnOperation> | ||||
|     interfaceAddress : OperationBuilder<AddColumnOperation> | ||||
|     name             : OperationBuilder<AddColumnOperation> | ||||
|     st               : OperationBuilder<AddColumnOperation> | ||||
|     } | ||||
| 
 | ||||
| type ListPreferencesTable = | ||||
|   { smallGroupId        : OperationBuilder<AddColumnOperation> | ||||
|     daysToExpire        : OperationBuilder<AddColumnOperation> | ||||
|     daysToKeepNew       : OperationBuilder<AddColumnOperation> | ||||
|     defaultEmailType    : OperationBuilder<AddColumnOperation> | ||||
|     emailFromAddress    : OperationBuilder<AddColumnOperation> | ||||
|     emailFromName       : OperationBuilder<AddColumnOperation> | ||||
|     groupPassword       : OperationBuilder<AddColumnOperation> | ||||
|     headingColor        : OperationBuilder<AddColumnOperation> | ||||
|     headingFontSize     : OperationBuilder<AddColumnOperation> | ||||
|     isPublic            : OperationBuilder<AddColumnOperation> | ||||
|     lineColor           : OperationBuilder<AddColumnOperation> | ||||
|     listFonts           : OperationBuilder<AddColumnOperation> | ||||
|     longTermUpdateWeeks : OperationBuilder<AddColumnOperation> | ||||
|     requestSort         : OperationBuilder<AddColumnOperation> | ||||
|     textFontSize        : OperationBuilder<AddColumnOperation> | ||||
|     timeZoneId          : OperationBuilder<AddColumnOperation> | ||||
|     pageSize            : OperationBuilder<AddColumnOperation> | ||||
|     asOfDateDisplay     : OperationBuilder<AddColumnOperation> | ||||
|     } | ||||
| 
 | ||||
| type MemberTable = | ||||
|   { memberId     : OperationBuilder<AddColumnOperation> | ||||
|     email        : OperationBuilder<AddColumnOperation> | ||||
|     format       : OperationBuilder<AddColumnOperation> | ||||
|     memberName   : OperationBuilder<AddColumnOperation> | ||||
|     smallGroupId : OperationBuilder<AddColumnOperation> | ||||
|     } | ||||
| 
 | ||||
| type PrayerRequestTable = | ||||
|   { 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 = | ||||
|   { smallGroupId : OperationBuilder<AddColumnOperation> | ||||
|     churchId     : OperationBuilder<AddColumnOperation> | ||||
|     name         : OperationBuilder<AddColumnOperation> | ||||
|     } | ||||
| 
 | ||||
| type TimeZoneTable = | ||||
|   { timeZoneId  : OperationBuilder<AddColumnOperation> | ||||
|     description : OperationBuilder<AddColumnOperation> | ||||
|     isActive    : OperationBuilder<AddColumnOperation> | ||||
|     sortOrder   : OperationBuilder<AddColumnOperation> | ||||
|     } | ||||
| 
 | ||||
| type UserSmallGroupTable = | ||||
|   { userId       : OperationBuilder<AddColumnOperation> | ||||
|     smallGroupId : OperationBuilder<AddColumnOperation> | ||||
|     } | ||||
| 
 | ||||
| type UserTable = | ||||
|   { userId       : OperationBuilder<AddColumnOperation> | ||||
|     emailAddress : OperationBuilder<AddColumnOperation> | ||||
|     firstName    : OperationBuilder<AddColumnOperation> | ||||
|     isAdmin      : OperationBuilder<AddColumnOperation> | ||||
|     lastName     : OperationBuilder<AddColumnOperation> | ||||
|     passwordHash : OperationBuilder<AddColumnOperation> | ||||
|     salt         : OperationBuilder<AddColumnOperation> | ||||
|     } | ||||
| 
 | ||||
| [<DbContext (typeof<AppDbContext>)>] | ||||
| [<Migration "20161217153124_InitialDatabase">] | ||||
| type InitialDatabase () = | ||||
|   inherit Migration () | ||||
|   override __.Up (migrationBuilder : MigrationBuilder) = | ||||
|     migrationBuilder.EnsureSchema (name = "pt") | ||||
|     |> ignore | ||||
|     inherit Migration () | ||||
|     override _.Up (migrationBuilder : MigrationBuilder) = | ||||
|         migrationBuilder.EnsureSchema (name = "pt") | ||||
|         |> ignore | ||||
| 
 | ||||
|     migrationBuilder.CreateTable ( | ||||
|       name    = "Church", | ||||
|       schema  = "pt", | ||||
|       columns = | ||||
|         (fun table -> | ||||
|             { 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",               nullable = false, maxLength = Nullable<int> 2) | ||||
|               }), | ||||
|       constraints = | ||||
|         fun table -> | ||||
|           table.PrimaryKey ("PK_Church", fun x -> upcast x.churchId) |> ignore) | ||||
|     |> ignore | ||||
|         migrationBuilder.CreateTable ( | ||||
|             name    = "church", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  Id               = table.Column<Guid>   (name = "id",                nullable = false) | ||||
|                     City             = table.Column<string> (name = "city",              nullable = false) | ||||
|                     HasVpsInterface  = table.Column<bool>   (name = "has_vps_interface", nullable = false) | ||||
|                     InterfaceAddress = table.Column<string> (name = "interface_address", nullable = true) | ||||
|                     Name             = table.Column<string> (name = "church_Name",       nullable = false) | ||||
|                     State            = table.Column<string> (name = "state",             nullable = false, maxLength = Nullable<int> 2) | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey ("pk_church", fun x -> upcast x.Id) |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     migrationBuilder.CreateTable ( | ||||
|       name    = "TimeZone", | ||||
|       schema  = "pt", | ||||
|       columns = | ||||
|         (fun table -> | ||||
|             { 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) | ||||
|               }), | ||||
|       constraints = | ||||
|         fun table -> | ||||
|           table.PrimaryKey ("PK_TimeZone", fun x -> upcast x.timeZoneId) |> ignore) | ||||
|     |> ignore | ||||
|         migrationBuilder.CreateTable ( | ||||
|             name    = "time_zone", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  Id          = table.Column<string> (name = "id",          nullable = false) | ||||
|                     Description = table.Column<string> (name = "description", nullable = false) | ||||
|                     IsActive    = table.Column<bool>   (name = "is_active",   nullable = false) | ||||
|                     SortOrder   = table.Column<int>    (name = "sort_order",  nullable = false) | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey ("pk_time_zone", fun x -> upcast x.Id) |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     migrationBuilder.CreateTable ( | ||||
|       name    = "User", | ||||
|       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) | ||||
|               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) | ||||
|               }), | ||||
|       constraints = | ||||
|         fun table -> | ||||
|           table.PrimaryKey("PK_User", fun x -> upcast x.userId) |> ignore) | ||||
|     |> ignore | ||||
|         migrationBuilder.CreateTable ( | ||||
|             name    = "pt_user", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  Id           = table.Column<Guid>   (name = "id",            nullable = false) | ||||
|                     Email        = table.Column<string> (name = "email",         nullable = false) | ||||
|                     FirstName    = table.Column<string> (name = "first_name",    nullable = false) | ||||
|                     IsAdmin      = table.Column<bool>   (name = "is_admin",      nullable = false) | ||||
|                     LastName     = table.Column<string> (name = "last_name",     nullable = false) | ||||
|                     PasswordHash = table.Column<string> (name = "password_hash", nullable = false) | ||||
|                     Salt         = table.Column<Guid>   (name = "salt",          nullable = true) | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey("pk_pt_user", fun x -> upcast x.Id) |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     migrationBuilder.CreateTable ( | ||||
|       name    = "SmallGroup", | ||||
|       schema  = "pt", | ||||
|       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) | ||||
|               }), | ||||
|       constraints = | ||||
|         fun table -> | ||||
|           table.PrimaryKey ("PK_SmallGroup", fun x -> upcast x.smallGroupId) |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_SmallGroup_Church_ChurchId", | ||||
|             column          = (fun x -> upcast x.churchId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "Church", | ||||
|             principalColumn = "ChurchId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         migrationBuilder.CreateTable ( | ||||
|             name    = "small_group", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  Id       = table.Column<Guid>   (name = "id",         nullable = false) | ||||
|                     ChurchId = table.Column<Guid>   (name = "church_id",  nullable = false) | ||||
|                     Name     = table.Column<string> (name = "group_name", nullable = false) | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey ("pk_small_group", fun x -> upcast x.Id) |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_small_group_church_id", | ||||
|                     column          = (fun x -> upcast x.ChurchId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "church", | ||||
|                     principalColumn = "id", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     migrationBuilder.CreateTable ( | ||||
|       name    = "ListPreference", | ||||
|       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") | ||||
|               longTermUpdateWeeks = table.Column<int>    (name = "LongTermUpdateWeeks", nullable = false, defaultValue = 4) | ||||
|               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 -> | ||||
|           table.PrimaryKey ("PK_ListPreference", fun x -> upcast x.smallGroupId) |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_ListPreference_SmallGroup_SmallGroupId", | ||||
|             column          = (fun x -> upcast x.smallGroupId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "SmallGroup", | ||||
|             principalColumn = "SmallGroupId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_ListPreference_TimeZone_TimeZoneId", | ||||
|             column          = (fun x -> upcast x.timeZoneId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "TimeZone", | ||||
|             principalColumn = "TimeZoneId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|      | ||||
|     migrationBuilder.CreateTable ( | ||||
|       name    = "Member", | ||||
|       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) | ||||
|               smallGroupId = table.Column<Guid>   (name = "SmallGroupId", nullable = false) | ||||
|               }), | ||||
|       constraints = | ||||
|         fun table -> | ||||
|           table.PrimaryKey ("PK_Member", fun x -> upcast x.memberId) |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_Member_SmallGroup_SmallGroupId", | ||||
|             column          = (fun x -> upcast x.smallGroupId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "SmallGroup", | ||||
|             principalColumn = "SmallGroupId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         migrationBuilder.CreateTable ( | ||||
|             name    = "list_preference", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  SmallGroupId        = table.Column<Guid>   (name = "small_group_id",         nullable = false) | ||||
|                     AsOfDateDisplay     = table.Column<string> (name = "as_of_date_display",     nullable = false, defaultValue = "N", maxLength = Nullable<int> 1) | ||||
|                     DaysToExpire        = table.Column<int>    (name = "days_to_expire",         nullable = false, defaultValue = 14) | ||||
|                     DaysToKeepNew       = table.Column<int>    (name = "days_to_keep_new",       nullable = false, defaultValue = 7) | ||||
|                     DefaultEmailType    = table.Column<string> (name = "default_email_type",     nullable = false, defaultValue = "Html") | ||||
|                     EmailFromAddress    = table.Column<string> (name = "email_from_address",     nullable = false, defaultValue = "prayer@djs-consulting.com") | ||||
|                     EmailFromName       = table.Column<string> (name = "email_from_name",        nullable = false, defaultValue = "PrayerTracker") | ||||
|                     Fonts               = table.Column<string> (name = "fonts",                  nullable = false, defaultValue = "Century Gothic,Tahoma,Luxi Sans,sans-serif") | ||||
|                     GroupPassword       = table.Column<string> (name = "group_password",         nullable = false, defaultValue = "") | ||||
|                     HeadingColor        = table.Column<string> (name = "heading_color",          nullable = false, defaultValue = "maroon") | ||||
|                     HeadingFontSize     = table.Column<int>    (name = "heading_font_size",      nullable = false, defaultValue = 16) | ||||
|                     IsPublic            = table.Column<bool>   (name = "is_public",              nullable = false, defaultValue = false) | ||||
|                     LineColor           = table.Column<string> (name = "line_color",             nullable = false, defaultValue = "navy") | ||||
|                     LongTermUpdateWeeks = table.Column<int>    (name = "long_term_update_weeks", nullable = false, defaultValue = 4) | ||||
|                     PageSize            = table.Column<int>    (name = "page_size",              nullable = false, defaultValue = 100) | ||||
|                     RequestSort         = table.Column<string> (name = "request_sort",           nullable = false, defaultValue = "D", maxLength = Nullable<int> 1) | ||||
|                     TextFontSize        = table.Column<int>    (name = "text_font_size",         nullable = false, defaultValue = 12) | ||||
|                     TimeZoneId          = table.Column<string> (name = "time_zone_id",           nullable = false, defaultValue = "America/Denver") | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey ("pk_list_preference", fun x -> upcast x.SmallGroupId) |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_list_preference_small_group_id", | ||||
|                     column          = (fun x -> upcast x.SmallGroupId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "small_group", | ||||
|                     principalColumn = "id", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_list_preference_time_zone_id", | ||||
|                     column          = (fun x -> upcast x.TimeZoneId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "time_zone", | ||||
|                     principalColumn = "id", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore) | ||||
|         |> ignore | ||||
|          | ||||
|         migrationBuilder.CreateTable ( | ||||
|             name    = "member", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  Id           = table.Column<Guid>   (name = "id",             nullable = false) | ||||
|                     Email        = table.Column<string> (name = "email",          nullable = false) | ||||
|                     Format       = table.Column<string> (name = "email_format",   nullable = true) | ||||
|                     Name         = table.Column<string> (name = "member_name",    nullable = false) | ||||
|                     SmallGroupId = table.Column<Guid>   (name = "small_group_id", nullable = false) | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey ("pk_member", fun x -> upcast x.Id) |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_member_small_group_id", | ||||
|                     column          = (fun x -> upcast x.SmallGroupId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "small_group", | ||||
|                     principalColumn = "id", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     migrationBuilder.CreateTable ( | ||||
|       name    = "PrayerRequest", | ||||
|       schema  = "pt", | ||||
|       columns = | ||||
|         (fun table -> | ||||
|             { prayerRequestId   = table.Column<Guid>     (name = "PrayerRequestId", 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 -> | ||||
|           table.PrimaryKey ("PK_PrayerRequest", fun x -> upcast x.prayerRequestId) |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_PrayerRequest_SmallGroup_SmallGroupId", | ||||
|             column          = (fun x -> upcast x.smallGroupId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "SmallGroup", | ||||
|             principalColumn = "SmallGroupId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_PrayerRequest_User_UserId", | ||||
|             column          = (fun x -> upcast x.userId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "User", | ||||
|             principalColumn = "UserId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|      | ||||
|     migrationBuilder.CreateTable( | ||||
|       name    = "User_SmallGroup", | ||||
|       schema  = "pt", | ||||
|       columns = | ||||
|         (fun table -> | ||||
|             { userId       = table.Column<Guid> (name = "UserId",       nullable = false) | ||||
|               smallGroupId = table.Column<Guid> (name = "SmallGroupId", nullable = false) | ||||
|               }), | ||||
|       constraints = | ||||
|         fun table -> | ||||
|           table.PrimaryKey ("PK_User_SmallGroup", fun x -> upcast x) |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_User_SmallGroup_SmallGroup_SmallGroupId", | ||||
|             column          = (fun x -> upcast x.smallGroupId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "SmallGroup", | ||||
|             principalColumn = "SmallGroupId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore | ||||
|           table.ForeignKey ( | ||||
|             name            = "FK_User_SmallGroup_User_UserId", | ||||
|             column          = (fun x -> upcast x.userId), | ||||
|             principalSchema = "pt", | ||||
|             principalTable  = "User", | ||||
|             principalColumn = "UserId", | ||||
|             onDelete        = ReferentialAction.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         migrationBuilder.CreateTable ( | ||||
|             name    = "prayer_request", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  Id             = table.Column<Guid>     (name = "id",              nullable = false) | ||||
|                     Expiration     = table.Column<bool>     (name = "expiration",      nullable = false) | ||||
|                     EnteredDate    = table.Column<DateTime> (name = "entered_date",    nullable = false) | ||||
|                     NotifyChaplain = table.Column<bool>     (name = "notify_chaplain", nullable = false) | ||||
|                     RequestType    = table.Column<string>   (name = "request_type",    nullable = false) | ||||
|                     Requestor      = table.Column<string>   (name = "requestor",       nullable = true) | ||||
|                     SmallGroupId   = table.Column<Guid>     (name = "small_group_id",  nullable = false) | ||||
|                     Text           = table.Column<string>   (name = "request_text",    nullable = false) | ||||
|                     UpdatedDate    = table.Column<DateTime> (name = "updated_date",    nullable = false) | ||||
|                     UserId         = table.Column<Guid>     (name = "user_id",         nullable = false) | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey ("pk_prayer_request", fun x -> upcast x.Id) |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_prayer_request_small_group_id", | ||||
|                     column          = (fun x -> upcast x.SmallGroupId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "small_group", | ||||
|                     principalColumn = "i", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_prayer_request_user_id", | ||||
|                     column          = (fun x -> upcast x.UserId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "pt_user", | ||||
|                     principalColumn = "id", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore) | ||||
|         |> ignore | ||||
|          | ||||
|         migrationBuilder.CreateTable( | ||||
|             name    = "user_small_group", | ||||
|             schema  = "pt", | ||||
|             columns = (fun table -> | ||||
|                 {|  UserId       = table.Column<Guid> (name = "user_id",        nullable = false) | ||||
|                     SmallGroupId = table.Column<Guid> (name = "small_group_id", nullable = false) | ||||
|                 |}), | ||||
|             constraints = fun table -> | ||||
|                 table.PrimaryKey ("pk_user_small_group", fun x -> upcast x) |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_user_small_group_small_group_id", | ||||
|                     column          = (fun x -> upcast x.SmallGroupId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "small_group", | ||||
|                     principalColumn = "id", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore | ||||
|                 table.ForeignKey ( | ||||
|                     name            = "fk_user_small_group_user_id", | ||||
|                     column          = (fun x -> upcast x.UserId), | ||||
|                     principalSchema = "pt", | ||||
|                     principalTable  = "pt_user", | ||||
|                     principalColumn = "id", | ||||
|                     onDelete        = ReferentialAction.Cascade) | ||||
|                 |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     migrationBuilder.CreateIndex (name = "IX_ListPreference_TimeZoneId",    schema = "pt", table = "ListPreference",  column = "TimeZoneId")   |> ignore | ||||
|     migrationBuilder.CreateIndex (name = "IX_Member_SmallGroupId",          schema = "pt", table = "Member",          column = "SmallGroupId") |> ignore | ||||
|     migrationBuilder.CreateIndex (name = "IX_PrayerRequest_SmallGroupId",   schema = "pt", table = "PrayerRequest",   column = "SmallGroupId") |> ignore | ||||
|     migrationBuilder.CreateIndex (name = "IX_PrayerRequest_UserId",         schema = "pt", table = "PrayerRequest",   column = "UserId")       |> ignore | ||||
|     migrationBuilder.CreateIndex (name = "IX_SmallGroup_ChurchId",          schema = "pt", table = "SmallGroup",      column = "ChurchId")     |> ignore | ||||
|     migrationBuilder.CreateIndex (name = "IX_User_SmallGroup_SmallGroupId", schema = "pt", table = "User_SmallGroup", column = "SmallGroupId") |> ignore | ||||
|         migrationBuilder.CreateIndex (name = "ix_list_preference_time_zone_id",    schema = "pt", table = "list_preference",  column = "time_zone_id")   |> ignore | ||||
|         migrationBuilder.CreateIndex (name = "ix_member_small_group_id",           schema = "pt", table = "member",           column = "small_group_id") |> ignore | ||||
|         migrationBuilder.CreateIndex (name = "ix_prayer_request_small_group_id",   schema = "pt", table = "prayer_request",   column = "small_group_id") |> ignore | ||||
|         migrationBuilder.CreateIndex (name = "ix_prayer_request_user_id",          schema = "pt", table = "prayer_request",   column = "user_id")        |> ignore | ||||
|         migrationBuilder.CreateIndex (name = "ix_small_group_church_id",           schema = "pt", table = "small_group",      column = "church_id")      |> ignore | ||||
|         migrationBuilder.CreateIndex (name = "ix_user_small_group_small_group_id", schema = "pt", table = "user_small_group", column = "small_group_id") |> ignore | ||||
|    | ||||
|   override __.Down (migrationBuilder : MigrationBuilder) = | ||||
|     migrationBuilder.DropTable (name = "ListPreference",  schema = "pt") |> ignore | ||||
|     migrationBuilder.DropTable (name = "Member",          schema = "pt") |> ignore | ||||
|     migrationBuilder.DropTable (name = "PrayerRequest",   schema = "pt") |> ignore | ||||
|     migrationBuilder.DropTable (name = "User_SmallGroup", schema = "pt") |> ignore | ||||
|     migrationBuilder.DropTable (name = "TimeZone",        schema = "pt") |> ignore | ||||
|     migrationBuilder.DropTable (name = "SmallGroup",      schema = "pt") |> ignore | ||||
|     migrationBuilder.DropTable (name = "User",            schema = "pt") |> ignore | ||||
|     migrationBuilder.DropTable (name = "Church",          schema = "pt") |> ignore | ||||
|     override _.Down (migrationBuilder : MigrationBuilder) = | ||||
|         migrationBuilder.DropTable (name = "list_preference",  schema = "pt") |> ignore | ||||
|         migrationBuilder.DropTable (name = "member",           schema = "pt") |> ignore | ||||
|         migrationBuilder.DropTable (name = "prayer_request",   schema = "pt") |> ignore | ||||
|         migrationBuilder.DropTable (name = "user_small_group", schema = "pt") |> ignore | ||||
|         migrationBuilder.DropTable (name = "time_zone",        schema = "pt") |> ignore | ||||
|         migrationBuilder.DropTable (name = "small_group",      schema = "pt") |> ignore | ||||
|         migrationBuilder.DropTable (name = "pt_user",          schema = "pt") |> ignore | ||||
|         migrationBuilder.DropTable (name = "church",           schema = "pt") |> ignore | ||||
| 
 | ||||
| 
 | ||||
|   override __.BuildTargetModel (modelBuilder : ModelBuilder) = | ||||
|     modelBuilder | ||||
|       .HasDefaultSchema("pt") | ||||
|       .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) | ||||
|       .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") | ||||
|     |> ignore | ||||
|     override _.BuildTargetModel (modelBuilder : ModelBuilder) = | ||||
|         modelBuilder | ||||
|             .HasDefaultSchema("pt") | ||||
|             .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) | ||||
|             .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<Church>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("churchId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("city").IsRequired() |> ignore | ||||
|           b.Property<bool>("hasInterface") |> ignore | ||||
|           b.Property<string>("interfaceAddress") |> ignore | ||||
|           b.Property<string>("name").IsRequired() |> ignore | ||||
|           b.Property<string>("st").IsRequired().HasMaxLength(2) |> ignore | ||||
|           b.HasKey("churchId") |> ignore | ||||
|           b.ToTable("Church") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<Church>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("City").HasColumnName("city").IsRequired() |> ignore | ||||
|             b.Property<bool>("HasVpsInterface").HasColumnName("has_vps_interface") |> ignore | ||||
|             b.Property<string>("InterfaceAddress").HasColumnName("interface_address") |> ignore | ||||
|             b.Property<string>("Name").HasColumnName("church_name").IsRequired() |> ignore | ||||
|             b.Property<string>("State").HasColumnName("state").IsRequired().HasMaxLength(2) |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.ToTable("church") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<ListPreferences>, | ||||
|       fun b -> | ||||
|           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("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 | ||||
|           b.Property<string>("headingColor").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("maroon") |> ignore | ||||
|           b.Property<int>("headingFontSize").ValueGeneratedOnAdd().HasDefaultValue(16) |> ignore | ||||
|           b.Property<bool>("isPublic").ValueGeneratedOnAdd().HasDefaultValue(false) |> ignore | ||||
|           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<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) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<ListPreferences>, fun b -> | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.Property<string>("AsOfDateDisplay").HasColumnName("as_of_date_display").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("N").HasMaxLength(1) |> ignore | ||||
|             b.Property<int>("DaysToExpire").HasColumnName("days_to_expire").ValueGeneratedOnAdd().HasDefaultValue(14) |> ignore | ||||
|             b.Property<int>("DaysToKeepNew").HasColumnName("days_to_keep_new").ValueGeneratedOnAdd().HasDefaultValue(7) |> ignore | ||||
|             b.Property<string>("DefaultEmailType").HasColumnName("default_email_type").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("H") |> ignore | ||||
|             b.Property<string>("EmailFromAddress").HasColumnName("email_from_address").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("prayer@djs-consulting.com") |> ignore | ||||
|             b.Property<string>("EmailFromName").HasColumnName("email_from_name").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("PrayerTracker") |> ignore | ||||
|             b.Property<string>("Fonts").HasColumnName("fonts").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("Century Gothic,Tahoma,Luxi Sans,sans-serif") |> ignore | ||||
|             b.Property<string>("GroupPassword").HasColumnName("group_password").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("") |> ignore | ||||
|             b.Property<string>("HeadingColor").HasColumnName("heading_color").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("maroon") |> ignore | ||||
|             b.Property<int>("HeadingFontSize").HasColumnName("heading_font_size").ValueGeneratedOnAdd().HasDefaultValue(16) |> ignore | ||||
|             b.Property<bool>("IsPublic").HasColumnName("is_public").ValueGeneratedOnAdd().HasDefaultValue(false) |> ignore | ||||
|             b.Property<string>("LineColor").HasColumnName("line_color").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("navy") |> ignore | ||||
|             b.Property<int>("LongTermUpdateWeeks").HasColumnName("long_term_update_weeks").ValueGeneratedOnAdd().HasDefaultValue(4) |> ignore | ||||
|             b.Property<int>("PageSize").HasColumnName("page_size").IsRequired().ValueGeneratedOnAdd().HasDefaultValue(100) |> ignore | ||||
|             b.Property<string>("RequestSort").HasColumnName("request_sort").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("D").HasMaxLength(1) |> ignore | ||||
|             b.Property<int>("TextFontSize").HasColumnName("text_font_size").ValueGeneratedOnAdd().HasDefaultValue(12) |> ignore | ||||
|             b.Property<string>("TimeZoneId").HasColumnName("time_zone_id").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("America/Denver") |> ignore | ||||
|             b.HasKey("SmallGroupId") |> ignore | ||||
|             b.HasIndex("TimeZoneId").HasDatabaseName "ix_list_preference_time_zone_id" |> ignore | ||||
|             b.ToTable("list_preference") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<Member>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("memberId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("email").IsRequired() |> ignore | ||||
|           b.Property<string>("format") |> ignore | ||||
|           b.Property<string>("memberName").IsRequired() |> ignore | ||||
|           b.Property<Guid>("smallGroupId") |> ignore | ||||
|           b.HasKey("memberId") |> ignore | ||||
|           b.HasIndex("smallGroupId") |> ignore | ||||
|           b.ToTable("Member") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<Member>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("Email").HasColumnName("email").IsRequired() |> ignore | ||||
|             b.Property<string>("Format").HasColumnName("email_format") |> ignore | ||||
|             b.Property<string>("Name").HasColumnName("member_name").IsRequired() |> ignore | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.HasIndex("SmallGroupId").HasDatabaseName "ix_member_small_group_id" |> ignore | ||||
|             b.ToTable("member") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<PrayerRequest>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("prayerRequestId").ValueGeneratedOnAdd() |> 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().HasMaxLength 1 |> ignore | ||||
|           b.Property<string>("requestor") |> ignore | ||||
|           b.Property<Guid>("smallGroupId") |> ignore | ||||
|           b.Property<string>("text").IsRequired() |> ignore | ||||
|           b.Property<DateTime>("updatedDate") |> ignore | ||||
|           b.Property<Guid>("userId") |> ignore | ||||
|           b.HasKey("prayerRequestId") |> ignore | ||||
|           b.HasIndex("smallGroupId") |> ignore | ||||
|           b.HasIndex("userId") |> ignore | ||||
|           b.ToTable("PrayerRequest") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<PrayerRequest>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<DateTime>("EnteredDate").HasColumnName("entered_date").IsRequired() |> ignore | ||||
|             b.Property<string>("Expiration").HasColumnName("expiration").IsRequired().HasMaxLength 1 |> ignore | ||||
|             b.Property<bool>("NotifyChaplain").HasColumnName("notify_chaplain") |> ignore | ||||
|             b.Property<string>("RequestType").HasColumnName("request_type").IsRequired().HasMaxLength 1 |> ignore | ||||
|             b.Property<string>("Requestor").HasColumnName("requestor") |> ignore | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.Property<string>("Text").HasColumnName("request_text").IsRequired() |> ignore | ||||
|             b.Property<DateTime>("UpdatedDate").HasColumnName("updated_date") |> ignore | ||||
|             b.Property<Guid>("UserId").HasColumnName("user_id") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.HasIndex("SmallGroupId").HasDatabaseName "ix_prayer_request_small_group_id" |> ignore | ||||
|             b.HasIndex("UserId").HasDatabaseName "ix_prayer_request_user_id" |> ignore | ||||
|             b.ToTable("prayer_request") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<SmallGroup>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("smallGroupId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<Guid>("churchId") |> ignore | ||||
|           b.Property<string>("name").IsRequired() |> ignore | ||||
|           b.HasKey("smallGroupId") |> ignore | ||||
|           b.HasIndex("churchId") |> ignore | ||||
|           b.ToTable("SmallGroup") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<SmallGroup>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<Guid>("ChurchId").HasColumnName("church_id") |> ignore | ||||
|             b.Property<string>("Name").HasColumnName("group_name").IsRequired() |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.HasIndex("ChurchId").HasDatabaseName "ix_small_group_church_id" |> ignore | ||||
|             b.ToTable("small_group") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<PrayerTracker.Entities.TimeZone>, | ||||
|       fun b -> | ||||
|           b.Property<string>("timeZoneId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("description").IsRequired() |> ignore | ||||
|           b.Property<bool>("isActive") |> ignore | ||||
|           b.Property<int>("sortOrder") |> ignore | ||||
|           b.HasKey("timeZoneId") |> ignore | ||||
|           b.ToTable("TimeZone") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<TimeZone>, fun b -> | ||||
|             b.Property<string>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("Description").HasColumnName("description").IsRequired() |> ignore | ||||
|             b.Property<bool>("IsActive").HasColumnName("is_active") |> ignore | ||||
|             b.Property<int>("SortOrder").HasColumnName("sort_order") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.ToTable("time_zone") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<User>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("userId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("emailAddress").IsRequired() |> ignore | ||||
|           b.Property<string>("firstName").IsRequired() |> ignore | ||||
|           b.Property<bool>("isAdmin") |> ignore | ||||
|           b.Property<string>("lastName").IsRequired() |> ignore | ||||
|           b.Property<string>("passwordHash").IsRequired() |> ignore | ||||
|           b.Property<Guid>("salt") |> ignore | ||||
|           b.HasKey("userId") |> ignore | ||||
|           b.ToTable("User") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<User>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("Email").HasColumnName("email").IsRequired() |> ignore | ||||
|             b.Property<string>("FirstName").HasColumnName("first_name").IsRequired() |> ignore | ||||
|             b.Property<bool>("IsAdmin").HasColumnName("is_admin") |> ignore | ||||
|             b.Property<string>("LastName").HasColumnName("last_name").IsRequired() |> ignore | ||||
|             b.Property<string>("PasswordHash").HasColumnName("password_hash").IsRequired() |> ignore | ||||
|             b.Property<Guid>("Salt").HasColumnName("salt") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.ToTable("pt_user") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<UserSmallGroup>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("userId") |> ignore | ||||
|           b.Property<Guid>("smallGroupId") |> ignore | ||||
|           b.HasKey("userId", "smallGroupId") |> ignore | ||||
|           b.HasIndex("smallGroupId") |> ignore | ||||
|           b.ToTable("User_SmallGroup") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<UserSmallGroup>, fun b -> | ||||
|             b.Property<Guid>("UserId").HasColumnName("user_id") |> ignore | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.HasKey("UserId", "SmallGroupId") |> ignore | ||||
|             b.HasIndex("SmallGroupId").HasDatabaseName "ix_user_small_group_small_group_id" |> ignore | ||||
|             b.ToTable("user_small_group") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<ListPreferences>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup") | ||||
|             .WithOne("preferences") | ||||
|             .HasForeignKey("PrayerTracker.Entities.ListPreferences", "smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore | ||||
|           b.HasOne("PrayerTracker.Entities.TimeZone", "timeZone") | ||||
|             .WithMany() | ||||
|             .HasForeignKey("timeZoneId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|      | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<Member>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup", "smallGroup") | ||||
|             .WithMany("members") | ||||
|             .HasForeignKey("smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<ListPreferences>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup") | ||||
|                 .WithOne("Preferences") | ||||
|                 .HasForeignKey("PrayerTracker.Entities.ListPreferences", "SmallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore | ||||
|             b.HasOne("PrayerTracker.Entities.TimeZone", "TimeZone") | ||||
|                 .WithMany() | ||||
|                 .HasForeignKey("TimeZoneId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
|          | ||||
|         modelBuilder.Entity (typeof<Member>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup", "SmallGroup") | ||||
|                 .WithMany("Members") | ||||
|                 .HasForeignKey("SmallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<PrayerRequest>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup", "smallGroup") | ||||
|             .WithMany("prayerRequests") | ||||
|             .HasForeignKey("smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore | ||||
|           b.HasOne("PrayerTracker.Entities.User", "user") | ||||
|             .WithMany() | ||||
|             .HasForeignKey("userId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<PrayerRequest>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup", "SmallGroup") | ||||
|                 .WithMany("PrayerRequests") | ||||
|                 .HasForeignKey("SmallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore | ||||
|             b.HasOne("PrayerTracker.Entities.User", "User") | ||||
|                 .WithMany() | ||||
|                 .HasForeignKey("UserId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<SmallGroup>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.Church", "Church") | ||||
|             .WithMany("SmallGroups") | ||||
|             .HasForeignKey("ChurchId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<SmallGroup>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.Church", "Church") | ||||
|                 .WithMany("SmallGroups") | ||||
|                 .HasForeignKey("ChurchId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<UserSmallGroup>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup", "smallGroup") | ||||
|             .WithMany("users") | ||||
|             .HasForeignKey("smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore | ||||
|           b.HasOne("PrayerTracker.Entities.User", "user") | ||||
|             .WithMany("smallGroups") | ||||
|             .HasForeignKey("userId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<UserSmallGroup>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup", "SmallGroup") | ||||
|                 .WithMany("Users") | ||||
|                 .HasForeignKey("SmallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore | ||||
|             b.HasOne("PrayerTracker.Entities.User", "User") | ||||
|                 .WithMany("SmallGroups") | ||||
|                 .HasForeignKey("UserId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
|  | ||||
| @ -1,200 +1,174 @@ | ||||
| namespace PrayerTracker.Migrations | ||||
| 
 | ||||
| open System | ||||
| open Microsoft.EntityFrameworkCore | ||||
| open Microsoft.EntityFrameworkCore.Infrastructure | ||||
| open Npgsql.EntityFrameworkCore.PostgreSQL.Metadata | ||||
| open PrayerTracker | ||||
| open PrayerTracker.Entities | ||||
| open System | ||||
| 
 | ||||
| [<DbContext (typeof<AppDbContext>)>] | ||||
| type AppDbContextModelSnapshot () = | ||||
|   inherit ModelSnapshot () | ||||
|     inherit ModelSnapshot () | ||||
| 
 | ||||
|   override __.BuildModel (modelBuilder : ModelBuilder) = | ||||
|     modelBuilder | ||||
|       .HasDefaultSchema("pt") | ||||
|       .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) | ||||
|       .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") | ||||
|     |> ignore | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<Church>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("churchId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("city").IsRequired() |> ignore | ||||
|           b.Property<bool>("hasInterface") |> ignore | ||||
|           b.Property<string>("interfaceAddress") |> ignore | ||||
|           b.Property<string>("name").IsRequired() |> ignore | ||||
|           b.Property<string>("st").IsRequired().HasMaxLength(2) |> ignore | ||||
|           b.HasKey("churchId") |> ignore | ||||
|           b.ToTable("Church") |> ignore) | ||||
|     |> ignore | ||||
|     override _.BuildModel (modelBuilder : ModelBuilder) = | ||||
|         modelBuilder | ||||
|             .HasDefaultSchema("pt") | ||||
|             .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) | ||||
|             .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") | ||||
|         |> ignore | ||||
|         modelBuilder.Entity (typeof<Church>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("City").HasColumnName("city").IsRequired() |> ignore | ||||
|             b.Property<bool>("HasVpsInterface").HasColumnName("has_vps_interface") |> ignore | ||||
|             b.Property<string>("InterfaceAddress").HasColumnName("interface_address") |> ignore | ||||
|             b.Property<string>("Name").HasColumnName("church_name").IsRequired() |> ignore | ||||
|             b.Property<string>("State").HasColumnName("state").IsRequired().HasMaxLength(2) |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.ToTable("church") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<ListPreferences>, | ||||
|       fun b -> | ||||
|           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("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 | ||||
|           b.Property<string>("headingColor").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("maroon") |> ignore | ||||
|           b.Property<int>("headingFontSize").ValueGeneratedOnAdd().HasDefaultValue(16) |> ignore | ||||
|           b.Property<bool>("isPublic").ValueGeneratedOnAdd().HasDefaultValue(false) |> ignore | ||||
|           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<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) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<ListPreferences>, fun b -> | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.Property<string>("AsOfDateDisplay").HasColumnName("as_of_date_display").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("N").HasMaxLength(1) |> ignore | ||||
|             b.Property<int>("DaysToExpire").HasColumnName("days_to_expire").ValueGeneratedOnAdd().HasDefaultValue(14) |> ignore | ||||
|             b.Property<int>("DaysToKeepNew").HasColumnName("days_to_keep_new").ValueGeneratedOnAdd().HasDefaultValue(7) |> ignore | ||||
|             b.Property<string>("DefaultEmailType").HasColumnName("default_email_type").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("H") |> ignore | ||||
|             b.Property<string>("EmailFromAddress").HasColumnName("email_from_address").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("prayer@djs-consulting.com") |> ignore | ||||
|             b.Property<string>("EmailFromName").HasColumnName("email_from_name").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("PrayerTracker") |> ignore | ||||
|             b.Property<string>("Fonts").HasColumnName("fonts").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("Century Gothic,Tahoma,Luxi Sans,sans-serif") |> ignore | ||||
|             b.Property<string>("GroupPassword").HasColumnName("group_password").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("") |> ignore | ||||
|             b.Property<string>("HeadingColor").HasColumnName("heading_color").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("maroon") |> ignore | ||||
|             b.Property<int>("HeadingFontSize").HasColumnName("heading_font_size").ValueGeneratedOnAdd().HasDefaultValue(16) |> ignore | ||||
|             b.Property<bool>("IsPublic").HasColumnName("is_public").ValueGeneratedOnAdd().HasDefaultValue(false) |> ignore | ||||
|             b.Property<string>("LineColor").HasColumnName("line_color").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("navy") |> ignore | ||||
|             b.Property<int>("LongTermUpdateWeeks").HasColumnName("long_term_update_weeks").ValueGeneratedOnAdd().HasDefaultValue(4) |> ignore | ||||
|             b.Property<int>("PageSize").HasColumnName("page_size").IsRequired().ValueGeneratedOnAdd().HasDefaultValue(100) |> ignore | ||||
|             b.Property<string>("RequestSort").HasColumnName("request_sort").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("D").HasMaxLength(1) |> ignore | ||||
|             b.Property<int>("TextFontSize").HasColumnName("text_font_size").ValueGeneratedOnAdd().HasDefaultValue(12) |> ignore | ||||
|             b.Property<string>("TimeZoneId").HasColumnName("time_zone_id").IsRequired().ValueGeneratedOnAdd().HasDefaultValue("America/Denver") |> ignore | ||||
|             b.HasKey("SmallGroupId") |> ignore | ||||
|             b.HasIndex("TimeZoneId").HasDatabaseName "ix_list_preference_time_zone_id" |> ignore | ||||
|             b.ToTable("list_preference") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<Member>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("memberId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("email").IsRequired() |> ignore | ||||
|           b.Property<string>("format") |> ignore | ||||
|           b.Property<string>("memberName").IsRequired() |> ignore | ||||
|           b.Property<Guid>("smallGroupId") |> ignore | ||||
|           b.HasKey("memberId") |> ignore | ||||
|           b.HasIndex("smallGroupId") |> ignore | ||||
|           b.ToTable("Member") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<Member>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("Email").HasColumnName("email").IsRequired() |> ignore | ||||
|             b.Property<string>("Format").HasColumnName("email_format") |> ignore | ||||
|             b.Property<string>("Name").HasColumnName("member_name").IsRequired() |> ignore | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.HasIndex("SmallGroupId").HasDatabaseName "ix_member_small_group_id" |> ignore | ||||
|             b.ToTable("member") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<PrayerRequest>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("prayerRequestId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<DateTime>("enteredDate") |> ignore | ||||
|           b.Property<string>("expiration").IsRequired().HasMaxLength(1) |> ignore | ||||
|           b.Property<bool>("notifyChaplain") |> 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 | ||||
|           b.Property<DateTime>("updatedDate") |> ignore | ||||
|           b.Property<Guid>("userId") |> ignore | ||||
|           b.HasKey("prayerRequestId") |> ignore | ||||
|           b.HasIndex("smallGroupId") |> ignore | ||||
|           b.HasIndex("userId") |> ignore | ||||
|           b.ToTable("PrayerRequest") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<PrayerRequest>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<DateTime>("EnteredDate").HasColumnName("entered_date").IsRequired() |> ignore | ||||
|             b.Property<string>("Expiration").HasColumnName("expiration").IsRequired().HasMaxLength 1 |> ignore | ||||
|             b.Property<bool>("NotifyChaplain").HasColumnName("notify_chaplain") |> ignore | ||||
|             b.Property<string>("RequestType").HasColumnName("request_type").IsRequired().HasMaxLength 1 |> ignore | ||||
|             b.Property<string>("Requestor").HasColumnName("requestor") |> ignore | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.Property<string>("Text").HasColumnName("request_text").IsRequired() |> ignore | ||||
|             b.Property<DateTime>("UpdatedDate").HasColumnName("updated_date") |> ignore | ||||
|             b.Property<Guid>("UserId").HasColumnName("user_id") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.HasIndex("SmallGroupId").HasDatabaseName "ix_prayer_request_small_group_id" |> ignore | ||||
|             b.HasIndex("UserId").HasDatabaseName "ix_prayer_request_user_id" |> ignore | ||||
|             b.ToTable("prayer_request") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<SmallGroup>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("smallGroupId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<Guid>("churchId") |> ignore | ||||
|           b.Property<string>("name").IsRequired() |> ignore | ||||
|           b.HasKey("smallGroupId") |> ignore | ||||
|           b.HasIndex("churchId") |> ignore | ||||
|           b.ToTable("SmallGroup") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<SmallGroup>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<Guid>("ChurchId").HasColumnName("church_id") |> ignore | ||||
|             b.Property<string>("Name").HasColumnName("group_name").IsRequired() |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.HasIndex("ChurchId").HasDatabaseName "ix_small_group_church_id" |> ignore | ||||
|             b.ToTable("small_group") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<PrayerTracker.Entities.TimeZone>, | ||||
|       fun b -> | ||||
|           b.Property<string>("timeZoneId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("description").IsRequired() |> ignore | ||||
|           b.Property<bool>("isActive") |> ignore | ||||
|           b.Property<int>("sortOrder") |> ignore | ||||
|           b.HasKey("timeZoneId") |> ignore | ||||
|           b.ToTable("TimeZone") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<TimeZone>, fun b -> | ||||
|             b.Property<string>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("Description").HasColumnName("description").IsRequired() |> ignore | ||||
|             b.Property<bool>("IsActive").HasColumnName("is_active") |> ignore | ||||
|             b.Property<int>("SortOrder").HasColumnName("sort_order") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.ToTable("time_zone") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<User>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("userId").ValueGeneratedOnAdd() |> ignore | ||||
|           b.Property<string>("emailAddress").IsRequired() |> ignore | ||||
|           b.Property<string>("firstName").IsRequired() |> ignore | ||||
|           b.Property<bool>("isAdmin") |> ignore | ||||
|           b.Property<string>("lastName").IsRequired() |> ignore | ||||
|           b.Property<string>("passwordHash").IsRequired() |> ignore | ||||
|           b.Property<Guid>("salt") |> ignore | ||||
|           b.HasKey("userId") |> ignore | ||||
|           b.ToTable("User") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<User>, fun b -> | ||||
|             b.Property<Guid>("Id").HasColumnName("id").ValueGeneratedOnAdd() |> ignore | ||||
|             b.Property<string>("Email").HasColumnName("email").IsRequired() |> ignore | ||||
|             b.Property<string>("FirstName").HasColumnName("first_name").IsRequired() |> ignore | ||||
|             b.Property<bool>("IsAdmin").HasColumnName("is_admin") |> ignore | ||||
|             b.Property<string>("LastName").HasColumnName("last_name").IsRequired() |> ignore | ||||
|             b.Property<string>("PasswordHash").HasColumnName("password_hash").IsRequired() |> ignore | ||||
|             b.Property<Guid>("Salt").HasColumnName("salt") |> ignore | ||||
|             b.HasKey("Id") |> ignore | ||||
|             b.ToTable("pt_user") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<UserSmallGroup>, | ||||
|       fun b -> | ||||
|           b.Property<Guid>("userId") |> ignore | ||||
|           b.Property<Guid>("smallGroupId") |> ignore | ||||
|           b.HasKey("userId", "smallGroupId") |> ignore | ||||
|           b.HasIndex("smallGroupId") |> ignore | ||||
|           b.ToTable("User_SmallGroup") |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<UserSmallGroup>, fun b -> | ||||
|             b.Property<Guid>("UserId").HasColumnName("user_id") |> ignore | ||||
|             b.Property<Guid>("SmallGroupId").HasColumnName("small_group_id") |> ignore | ||||
|             b.HasKey("UserId", "SmallGroupId") |> ignore | ||||
|             b.HasIndex("SmallGroupId").HasDatabaseName "ix_user_small_group_small_group_id" |> ignore | ||||
|             b.ToTable("user_small_group") |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<ListPreferences>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup") | ||||
|             .WithOne("preferences") | ||||
|             .HasForeignKey("PrayerTracker.Entities.ListPreferences", "smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore | ||||
|           b.HasOne("PrayerTracker.Entities.TimeZone", "timeZone") | ||||
|             .WithMany() | ||||
|             .HasForeignKey("timeZoneId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|      | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<Member>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup", "smallGroup") | ||||
|             .WithMany("members") | ||||
|             .HasForeignKey("smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<ListPreferences>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup") | ||||
|                 .WithOne("Preferences") | ||||
|                 .HasForeignKey("PrayerTracker.Entities.ListPreferences", "smallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore | ||||
|             b.HasOne("PrayerTracker.Entities.TimeZone", "TimeZone") | ||||
|                 .WithMany() | ||||
|                 .HasForeignKey("TimeZoneId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
|          | ||||
|         modelBuilder.Entity (typeof<Member>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup", "SmallGroup") | ||||
|                 .WithMany("Members") | ||||
|                 .HasForeignKey("SmallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<PrayerRequest>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup", "smallGroup") | ||||
|             .WithMany("prayerRequests") | ||||
|             .HasForeignKey("smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore | ||||
|           b.HasOne("PrayerTracker.Entities.User", "user") | ||||
|             .WithMany() | ||||
|             .HasForeignKey("userId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<PrayerRequest>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup", "SmallGroup") | ||||
|                 .WithMany("PrayerRequests") | ||||
|                 .HasForeignKey("SmallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore | ||||
|             b.HasOne("PrayerTracker.Entities.User", "User") | ||||
|                 .WithMany() | ||||
|                 .HasForeignKey("UserId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<SmallGroup>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.Church", "Church") | ||||
|             .WithMany("SmallGroups") | ||||
|             .HasForeignKey("ChurchId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<SmallGroup>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.Church", "Church") | ||||
|                 .WithMany("SmallGroups") | ||||
|                 .HasForeignKey("ChurchId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
| 
 | ||||
|     modelBuilder.Entity ( | ||||
|       typeof<UserSmallGroup>, | ||||
|       fun b -> | ||||
|           b.HasOne("PrayerTracker.Entities.SmallGroup", "smallGroup") | ||||
|             .WithMany("users") | ||||
|             .HasForeignKey("smallGroupId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore | ||||
|           b.HasOne("PrayerTracker.Entities.User", "user") | ||||
|             .WithMany("smallGroups") | ||||
|             .HasForeignKey("userId") | ||||
|             .OnDelete(DeleteBehavior.Cascade) | ||||
|           |> ignore) | ||||
|     |> ignore | ||||
|         modelBuilder.Entity (typeof<UserSmallGroup>, fun b -> | ||||
|             b.HasOne("PrayerTracker.Entities.SmallGroup", "SmallGroup") | ||||
|                 .WithMany("Users") | ||||
|                 .HasForeignKey("SmallGroupId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore | ||||
|             b.HasOne("PrayerTracker.Entities.User", "User") | ||||
|                 .WithMany("SmallGroups") | ||||
|                 .HasForeignKey("UserId") | ||||
|                 .OnDelete(DeleteBehavior.Cascade) | ||||
|             |> ignore) | ||||
|         |> ignore | ||||
|  | ||||
| @ -41,7 +41,7 @@ let churchTests = | ||||
|             Expect.equal mt.Name "" "The name should have been blank" | ||||
|             Expect.equal mt.City "" "The city should have been blank" | ||||
|             Expect.equal mt.State "" "The state should have been blank" | ||||
|             Expect.isFalse mt.HasInterface "The church should not show that it has an interface" | ||||
|             Expect.isFalse mt.HasVpsInterface "The church should not show that it has an interface" | ||||
|             Expect.isNone mt.InterfaceAddress "The interface address should not exist" | ||||
|             Expect.isNotNull mt.SmallGroups "The small groups navigation property should not be null" | ||||
|             Expect.isEmpty mt.SmallGroups "There should be no small groups for an empty church" | ||||
| @ -159,61 +159,61 @@ let prayerRequestTests = | ||||
|             Expect.equal mt.User.Id.Value Guid.Empty "The user should have been an empty one" | ||||
|             Expect.equal mt.SmallGroup.Id.Value Guid.Empty "The small group should have been an empty one" | ||||
|         } | ||||
|         test "isExpired always returns false for expecting requests" { | ||||
|         test "IsExpired always returns false for expecting requests" { | ||||
|             let req = { PrayerRequest.empty with RequestType = Expecting } | ||||
|             Expect.isFalse (req.isExpired DateTime.Now 0) "An expecting request should never be considered expired" | ||||
|             Expect.isFalse (req.IsExpired DateTime.Now 0) "An expecting request should never be considered expired" | ||||
|         } | ||||
|         test "isExpired always returns false for manually-expired requests" { | ||||
|         test "IsExpired always returns false for manually-expired requests" { | ||||
|             let req = { PrayerRequest.empty with UpdatedDate = DateTime.Now.AddMonths -1; Expiration = Manual } | ||||
|             Expect.isFalse (req.isExpired DateTime.Now 4) "A never-expired request should never be considered expired" | ||||
|             Expect.isFalse (req.IsExpired DateTime.Now 4) "A never-expired request should never be considered expired" | ||||
|         } | ||||
|         test "isExpired always returns false for long term/recurring requests" { | ||||
|         test "IsExpired always returns false for long term/recurring requests" { | ||||
|             let req = { PrayerRequest.empty with RequestType = LongTermRequest } | ||||
|             Expect.isFalse (req.isExpired DateTime.Now 0) | ||||
|             Expect.isFalse (req.IsExpired DateTime.Now 0) | ||||
|                 "A recurring/long-term request should never be considered expired" | ||||
|         } | ||||
|         test "isExpired always returns true for force-expired requests" { | ||||
|         test "IsExpired always returns true for force-expired requests" { | ||||
|             let req = { PrayerRequest.empty with UpdatedDate = DateTime.Now; Expiration = Forced } | ||||
|             Expect.isTrue (req.isExpired DateTime.Now 5) "A force-expired request should always be considered expired" | ||||
|             Expect.isTrue (req.IsExpired DateTime.Now 5) "A force-expired request should always be considered expired" | ||||
|         } | ||||
|         test "isExpired returns false for non-expired requests" { | ||||
|         test "IsExpired returns false for non-expired requests" { | ||||
|             let now = DateTime.Now | ||||
|             let req = { PrayerRequest.empty with UpdatedDate = now.AddDays -5. } | ||||
|             Expect.isFalse (req.isExpired now 7) "A request updated 5 days ago should not be considered expired" | ||||
|             Expect.isFalse (req.IsExpired now 7) "A request updated 5 days ago should not be considered expired" | ||||
|         } | ||||
|         test "isExpired returns true for expired requests" { | ||||
|         test "IsExpired returns true for expired requests" { | ||||
|             let now = DateTime.Now | ||||
|             let req = { PrayerRequest.empty with UpdatedDate = now.AddDays -8. } | ||||
|             Expect.isTrue (req.isExpired now 7) "A request updated 8 days ago should be considered expired" | ||||
|             Expect.isTrue (req.IsExpired now 7) "A request updated 8 days ago should be considered expired" | ||||
|         } | ||||
|         test "isExpired returns true for same-day expired requests" { | ||||
|         test "IsExpired returns true for same-day expired requests" { | ||||
|             let now = DateTime.Now | ||||
|             let req = { PrayerRequest.empty with UpdatedDate = now.Date.AddDays(-7.).AddSeconds -1. } | ||||
|             Expect.isTrue (req.isExpired now 7) | ||||
|             Expect.isTrue (req.IsExpired now 7) | ||||
|                 "A request entered a second before midnight should be considered expired" | ||||
|         } | ||||
|         test "updateRequired returns false for expired requests" { | ||||
|         test "UpdateRequired returns false for expired requests" { | ||||
|             let req = { PrayerRequest.empty with Expiration = Forced } | ||||
|             Expect.isFalse (req.updateRequired DateTime.Now 7 4) "An expired request should not require an update" | ||||
|             Expect.isFalse (req.UpdateRequired DateTime.Now 7 4) "An expired request should not require an update" | ||||
|         } | ||||
|         test "updateRequired returns false when an update is not required for an active request" { | ||||
|         test "UpdateRequired returns false when an update is not required for an active request" { | ||||
|             let now = DateTime.Now | ||||
|             let req = | ||||
|                 { PrayerRequest.empty with | ||||
|                     RequestType = LongTermRequest | ||||
|                     UpdatedDate = now.AddDays -14. | ||||
|                 } | ||||
|             Expect.isFalse (req.updateRequired now 7 4) | ||||
|             Expect.isFalse (req.UpdateRequired now 7 4) | ||||
|                 "An active request updated 14 days ago should not require an update until 28 days" | ||||
|         } | ||||
|         test "updateRequired returns true when an update is required for an active request" { | ||||
|         test "UpdateRequired returns true when an update is required for an active request" { | ||||
|             let now = DateTime.Now | ||||
|             let req = | ||||
|                 { PrayerRequest.empty with | ||||
|                     RequestType = LongTermRequest | ||||
|                     UpdatedDate = now.AddDays -34. | ||||
|                 } | ||||
|             Expect.isTrue (req.updateRequired now 7 4) | ||||
|             Expect.isTrue (req.UpdateRequired now 7 4) | ||||
|                 "An active request updated 34 days ago should require an update (past 28 days)" | ||||
|         } | ||||
|     ] | ||||
| @ -305,33 +305,33 @@ let smallGroupTests = | ||||
|             Expect.isEmpty mt.Users "There should be no users for an empty small group" | ||||
|         } | ||||
|         yield! testFixture withFakeClock [ | ||||
|             "localTimeNow adjusts the time ahead of UTC", | ||||
|             "LocalTimeNow adjusts the time ahead of UTC", | ||||
|             fun clock -> | ||||
|                 let grp = | ||||
|                     { SmallGroup.empty with | ||||
|                         Preferences = { ListPreferences.empty with TimeZoneId = TimeZoneId "Europe/Berlin" } | ||||
|                     } | ||||
|                 Expect.isGreaterThan (grp.localTimeNow clock) now "UTC to Europe/Berlin should have added hours" | ||||
|             "localTimeNow adjusts the time behind UTC", | ||||
|                 Expect.isGreaterThan (grp.LocalTimeNow clock) now "UTC to Europe/Berlin should have added hours" | ||||
|             "LocalTimeNow adjusts the time behind UTC", | ||||
|             fun clock -> | ||||
|                 Expect.isLessThan (SmallGroup.empty.localTimeNow clock) now | ||||
|                 Expect.isLessThan (SmallGroup.empty.LocalTimeNow clock) now | ||||
|                     "UTC to America/Denver should have subtracted hours" | ||||
|             "localTimeNow returns UTC when the time zone is invalid", | ||||
|             "LocalTimeNow returns UTC when the time zone is invalid", | ||||
|             fun clock -> | ||||
|                 let grp = | ||||
|                     { SmallGroup.empty with | ||||
|                         Preferences = { ListPreferences.empty with TimeZoneId = TimeZoneId "garbage" } | ||||
|                     } | ||||
|                 Expect.equal (grp.localTimeNow clock) now "UTC should have been returned for an invalid time zone" | ||||
|                 Expect.equal (grp.LocalTimeNow clock) now "UTC should have been returned for an invalid time zone" | ||||
|         ] | ||||
|         yield test "localTimeNow fails when clock is not passed" { | ||||
|             Expect.throws (fun () -> (SmallGroup.empty.localTimeNow >> ignore) null) | ||||
|         yield test "LocalTimeNow fails when clock is not passed" { | ||||
|             Expect.throws (fun () -> (SmallGroup.empty.LocalTimeNow >> ignore) null) | ||||
|                 "Should have raised an exception for null clock" | ||||
|         } | ||||
|         yield test "localDateNow returns the date portion" { | ||||
|         yield test "LocalDateNow returns the date portion" { | ||||
|             let now'  = DateTime (2017, 5, 12, 1, 15, 0, DateTimeKind.Utc) | ||||
|             let clock = FakeClock (Instant.FromDateTimeUtc now') | ||||
|             Expect.isLessThan (SmallGroup.empty.localDateNow clock) now.Date "The date should have been a day earlier" | ||||
|             Expect.isLessThan (SmallGroup.empty.LocalDateNow clock) now.Date "The date should have been a day earlier" | ||||
|         } | ||||
|     ] | ||||
| 
 | ||||
| @ -362,9 +362,9 @@ let userTests = | ||||
|             Expect.isNotNull mt.SmallGroups "The small groups navigation property should not have been null" | ||||
|             Expect.isEmpty mt.SmallGroups "There should be no small groups for an empty user" | ||||
|         } | ||||
|         test "fullName concatenates first and last names" { | ||||
|         test "Name concatenates first and last names" { | ||||
|             let user = { User.empty with FirstName = "Unit"; LastName = "Test" } | ||||
|             Expect.equal user.fullName "Unit Test" "The full name should be the first and last, separated by a space" | ||||
|             Expect.equal user.Name "Unit Test" "The full name should be the first and last, separated by a space" | ||||
|         } | ||||
|     ] | ||||
| 
 | ||||
|  | ||||
| @ -118,7 +118,6 @@ let appViewInfoTests = | ||||
|         test "fresh is constructed properly" { | ||||
|             let vi = AppViewInfo.fresh | ||||
|             Expect.isEmpty vi.Style "There should have been no styles set" | ||||
|             Expect.isEmpty vi.Script "There should have been no scripts set" | ||||
|             Expect.isNone vi.HelpLink "The help link should have been set to none" | ||||
|             Expect.isEmpty vi.Messages "There should have been no messages set" | ||||
|             Expect.equal vi.Version "" "The version should have been blank" | ||||
| @ -135,7 +134,7 @@ let assignGroupsTests = | ||||
|             let usr = { User.empty with Id = (Guid.NewGuid >> UserId) (); FirstName = "Alice"; LastName = "Bob" } | ||||
|             let asg = AssignGroups.fromUser usr | ||||
|             Expect.equal asg.UserId (shortGuid usr.Id.Value) "The user ID was not filled correctly" | ||||
|             Expect.equal asg.UserName usr.fullName "The user name was not filled correctly" | ||||
|             Expect.equal asg.UserName usr.Name "The user's name was not filled correctly" | ||||
|             Expect.equal asg.SmallGroups "" "The small group string was not filled correctly" | ||||
|         } | ||||
|     ] | ||||
| @ -150,7 +149,7 @@ let editChurchTests = | ||||
|                     Name             = "Unit Test" | ||||
|                     City             = "Testlandia" | ||||
|                     State            = "UT" | ||||
|                     HasInterface     = true | ||||
|                     HasVpsInterface  = true | ||||
|                     InterfaceAddress = Some "https://test-dem-units.test" | ||||
|                   } | ||||
|             let edit = EditChurch.fromChurch church | ||||
| @ -159,7 +158,7 @@ let editChurchTests = | ||||
|             Expect.equal edit.City church.City "The church's city was not filled correctly" | ||||
|             Expect.equal edit.State church.State "The church's state was not filled correctly" | ||||
|             Expect.isSome edit.HasInterface "The church should show that it has an interface" | ||||
|             Expect.equal edit.HasInterface (Some true) "The hasInterface flag should be true" | ||||
|             Expect.equal edit.HasInterface (Some true) "The HasVpsInterface flag should be true" | ||||
|             Expect.isSome edit.InterfaceAddress "The interface address should exist" | ||||
|             Expect.equal edit.InterfaceAddress church.InterfaceAddress "The interface address was not filled correctly" | ||||
|         } | ||||
| @ -206,7 +205,7 @@ let editChurchTests = | ||||
|             Expect.equal church.Name edit.Name "The church name was not updated correctly" | ||||
|             Expect.equal church.City edit.City "The church's city was not updated correctly" | ||||
|             Expect.equal church.State edit.State "The church's state was not updated correctly" | ||||
|             Expect.isTrue church.HasInterface "The church should show that it has an interface" | ||||
|             Expect.isTrue church.HasVpsInterface "The church should show that it has an interface" | ||||
|             Expect.isSome church.InterfaceAddress "The interface address should exist" | ||||
|             Expect.equal church.InterfaceAddress edit.InterfaceAddress "The interface address was not updated correctly" | ||||
|         } | ||||
| @ -217,7 +216,7 @@ let editChurchTests = | ||||
|                     City  = "Testerville" | ||||
|                     State = "TE" | ||||
|                   }.PopulateChurch Church.empty | ||||
|             Expect.isFalse church.HasInterface "The church should show that it has an interface" | ||||
|             Expect.isFalse church.HasVpsInterface "The church should show that it has an interface" | ||||
|             Expect.isNone church.InterfaceAddress "The interface address should exist" | ||||
|         } | ||||
|     ] | ||||
| @ -284,7 +283,7 @@ let editPreferencesTests = | ||||
|             Expect.equal edit.TimeZone (TimeZoneId.toString prefs.TimeZoneId) "The time zone was not filled correctly" | ||||
|             Expect.isSome edit.GroupPassword "The group password should have been set" | ||||
|             Expect.equal edit.GroupPassword (Some prefs.GroupPassword) "The group password was not filled correctly" | ||||
|             Expect.equal edit.Visibility RequestVisibility.``private`` | ||||
|             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) | ||||
| @ -297,7 +296,7 @@ let editPreferencesTests = | ||||
|             Expect.equal edit.LineColor prefs.LineColor "The heading line color was not filled correctly" | ||||
|             Expect.isSome edit.GroupPassword "The group password should have been set" | ||||
|             Expect.equal edit.GroupPassword (Some prefs.GroupPassword) "The group password was not filled correctly" | ||||
|             Expect.equal edit.Visibility RequestVisibility.passwordProtected | ||||
|             Expect.equal edit.Visibility GroupVisibility.HasPassword | ||||
|                 "The list visibility was not derived correctly" | ||||
|         } | ||||
|         test "fromPreferences succeeds for RGB text color and public list" { | ||||
| @ -307,7 +306,7 @@ let editPreferencesTests = | ||||
|             Expect.equal edit.HeadingColor prefs.HeadingColor "The heading text color was not filled correctly" | ||||
|             Expect.isSome edit.GroupPassword "The group password should have been set" | ||||
|             Expect.equal edit.GroupPassword (Some "") "The group password was not filled correctly" | ||||
|             Expect.equal edit.Visibility RequestVisibility.``public`` | ||||
|             Expect.equal edit.Visibility GroupVisibility.PublicList | ||||
|                 "The list visibility was not derived correctly" | ||||
|         } | ||||
|     ] | ||||
|  | ||||
| @ -84,7 +84,7 @@ let maintain (churches : Church list) (stats : Map<string, ChurchStats>) ctx vi | ||||
|                         td [ _class "pt-right-text" ] [ rawText (stats[chId].SmallGroups.ToString "N0") ] | ||||
|                         td [ _class "pt-right-text" ] [ rawText (stats[chId].PrayerRequests.ToString "N0") ] | ||||
|                         td [ _class "pt-right-text" ] [ rawText (stats[chId].Users.ToString "N0") ] | ||||
|                         td [ _class "pt-center-text" ] [ locStr s[if ch.HasInterface then "Yes" else "No"] ] | ||||
|                         td [ _class "pt-center-text" ] [ locStr s[if ch.HasVpsInterface then "Yes" else "No"] ] | ||||
|                     ]) | ||||
|                 |> tbody [] | ||||
|             ] | ||||
|  | ||||
| @ -159,7 +159,7 @@ module Navigation = | ||||
|                         span [ _class "u" ] [ locStr s["Currently Logged On"] ] | ||||
|                         rawText "   " | ||||
|                         icon "person" | ||||
|                         strong [] [ str u.fullName ] | ||||
|                         strong [] [ str u.Name ] | ||||
|                         rawText "    " | ||||
|                     | None -> | ||||
|                         locStr s["Logged On as a Member of"] | ||||
| @ -169,7 +169,6 @@ module Navigation = | ||||
|                     match m.User with | ||||
|                     | Some _ -> a [ _href "/small-group"; Target.content ] [ strong [] [ str g.Name ] ] | ||||
|                     | None -> strong [] [ str g.Name ] | ||||
|                     rawText "  " | ||||
|                 ] | ||||
|             | None -> [] | ||||
|             |> div [] | ||||
| @ -263,12 +262,12 @@ let private htmlFooter viewInfo = | ||||
|     let s          = I18N.localizer.Force () | ||||
|     let imgText    = $"""%O{s["PrayerTracker"]} %O{s["from Bit Badger Solutions"]}""" | ||||
|     let resultTime = TimeSpan(DateTime.Now.Ticks - viewInfo.RequestStart).TotalSeconds | ||||
|     footer [] [ | ||||
|     footer [ _class "pt-footer" ] [ | ||||
|         div [ _id "pt-legal" ] [ | ||||
|             a [ _href "/legal/privacy-policy" ] [ locStr s["Privacy Policy"] ] | ||||
|             rawText " • " | ||||
|             rawText "   " | ||||
|             a [ _href "/legal/terms-of-service" ] [ locStr s["Terms of Service"] ] | ||||
|             rawText " • " | ||||
|             rawText "   " | ||||
|             a [ _href   "https://github.com/bit-badger/PrayerTracker" | ||||
|                 _title  s["View source code and get technical support"].Value | ||||
|                 _target "_blank" | ||||
| @ -278,7 +277,10 @@ let private htmlFooter viewInfo = | ||||
|         ] | ||||
|         div [ _id "pt-footer" ] [ | ||||
|             a [ _href "/"; _style "line-height:28px;" ] [ | ||||
|                 img [ _src $"""/img/%O{s["footer_en"]}.png"""; _alt imgText; _title imgText ] | ||||
|                 img [ _src   $"""/img/%O{s["footer_en"]}.png""" | ||||
|                       _alt   imgText | ||||
|                       _title imgText | ||||
|                       _width "331"; _height "28" ] | ||||
|             ] | ||||
|             str viewInfo.Version | ||||
|             space | ||||
| @ -286,8 +288,6 @@ let private htmlFooter viewInfo = | ||||
|                 str "schedule" | ||||
|             ] | ||||
|         ] | ||||
|         Script.minified | ||||
|         script [ _src "/js/app.js" ] [] | ||||
|     ] | ||||
| 
 | ||||
| /// The content portion of the PrayerTracker layout | ||||
| @ -297,13 +297,21 @@ let private contentSection viewInfo pgTitle (content : XmlNode) = [ | ||||
|     yield! messages viewInfo | ||||
|     match viewInfo.ScopedStyle with | ||||
|     | [] -> () | ||||
|     | styles -> style [ _scoped ] (styles |> List.map (fun it -> rawText $"{it}; ")) | ||||
|     | styles -> style [] [ rawText (styles |> String.concat " ") ] | ||||
|     content | ||||
|     htmlFooter viewInfo | ||||
|     for jsFile in viewInfo.Script do | ||||
|         script [ _src $"/js/{jsFile}.js" ] [] | ||||
|     match viewInfo.OnLoadScript with | ||||
|     | Some onLoad -> script [] [ rawText $"{onLoad}()" ] | ||||
|     | Some onLoad -> | ||||
|         script [] [ | ||||
|             rawText $""" | ||||
|                 window.doOnLoad = () => {{ | ||||
|                     if (window.PT) {{ | ||||
|                         {onLoad}() | ||||
|                         delete window.doOnLoad | ||||
|                     }} else {{ setTimeout(window.doOnLoad, 500) }} | ||||
|                 }} | ||||
|                 window.doOnLoad()""" | ||||
|         ] | ||||
|     | None -> () | ||||
| ] | ||||
| 
 | ||||
| @ -323,6 +331,12 @@ let private pageLayout viewInfo pgTitle content = | ||||
|         Navigation.top viewInfo | ||||
|         div [ _id "pt-body"; Target.content; _hxSwap $"{HxSwap.InnerHtml} show:window:top" ] | ||||
|             (contentSection viewInfo pgTitle content) | ||||
|         match viewInfo.Layout with | ||||
|         | FullPage -> | ||||
|             Script.minified | ||||
|             script [ _src "/js/ckeditor/ckeditor.js" ] [] | ||||
|             script [ _src "/js/app.js" ] [] | ||||
|         | _ -> () | ||||
|     ] | ||||
|      | ||||
| /// The standard layout(s) for PrayerTracker | ||||
|  | ||||
| @ -152,14 +152,14 @@ let maintain (model : MaintainRequests) (ctx : HttpContext) viewInfo = | ||||
|     let l     = I18N.forView "Requests/Maintain" | ||||
|     use sw    = new StringWriter () | ||||
|     let raw   = rawLocText sw | ||||
|     let now   = model.SmallGroup.localDateNow (ctx.GetService<IClock> ()) | ||||
|     let now   = model.SmallGroup.LocalDateNow (ctx.GetService<IClock> ()) | ||||
|     let prefs = model.SmallGroup.Preferences | ||||
|     let types = ReferenceList.requestTypeList s |> Map.ofList | ||||
|     let updReq (req : PrayerRequest) = | ||||
|         if req.updateRequired now prefs.DaysToExpire prefs.LongTermUpdateWeeks then "pt-request-update" else "" | ||||
|         if req.UpdateRequired now prefs.DaysToExpire prefs.LongTermUpdateWeeks then "pt-request-update" else "" | ||||
|         |> _class  | ||||
|     let reqExp (req : PrayerRequest) = | ||||
|         _class (if req.isExpired now prefs.DaysToExpire then "pt-request-expired" else "") | ||||
|         _class (if req.IsExpired now prefs.DaysToExpire then "pt-request-expired" else "") | ||||
|     /// Iterate the sequence once, before we render, so we can get the count of it at the top of the table | ||||
|     let requests = | ||||
|         model.Requests | ||||
| @ -180,7 +180,7 @@ let maintain (model : MaintainRequests) (ctx : HttpContext) viewInfo = | ||||
|                     a [ _href $"/prayer-request/{reqId}/edit"; _title l["Edit This Prayer Request"].Value ] [ | ||||
|                         icon "edit" | ||||
|                     ] | ||||
|                     if req.isExpired now prefs.DaysToExpire then | ||||
|                     if req.IsExpired now prefs.DaysToExpire then | ||||
|                         a [ _href  $"/prayer-request/{reqId}/restore" | ||||
|                             _title l["Restore This Inactive Request"].Value ] [ | ||||
|                             icon "visibility" | ||||
| @ -305,39 +305,40 @@ let view model viewInfo = | ||||
|     let pageTitle = $"""{s["Prayer Requests"].Value} • {model.SmallGroup.Name}""" | ||||
|     let spacer    = rawText "       " | ||||
|     let dtString  = model.Date.ToString "yyyy-MM-dd" | ||||
|     div [ _class "pt-center-text" ] [ | ||||
|         br [] | ||||
|         a [ _class  "pt-icon-link" | ||||
|             _href   $"/prayer-requests/print/{dtString}" | ||||
|             _target "_blank" | ||||
|             _title  s["View Printable"].Value ] [ | ||||
|             icon "print"; rawText "  "; locStr s["View Printable"] | ||||
|         ] | ||||
|         if model.CanEmail then | ||||
|             spacer | ||||
|             if model.Date.DayOfWeek <> DayOfWeek.Sunday then | ||||
|                 let rec findSunday (date : DateTime) = | ||||
|                     if date.DayOfWeek = DayOfWeek.Sunday then date else findSunday (date.AddDays 1.) | ||||
|                 let sunday = findSunday model.Date | ||||
|                 a [ _class "pt-icon-link" | ||||
|                     _href  $"""/prayer-requests/view/{sunday.ToString "yyyy-MM-dd"}""" | ||||
|                     _title s["List for Next Sunday"].Value ] [ | ||||
|                     icon "update"; rawText "  "; locStr s["List for Next Sunday"] | ||||
|                 ] | ||||
|                 spacer | ||||
|             let emailPrompt = s["This will e-mail the current list to every member of your group, without further prompting.  Are you sure this is what you are ready to do?"].Value | ||||
|             a [ _class   "pt-icon-link" | ||||
|                 _href    $"/prayer-requests/email/{dtString}" | ||||
|                 _title   s["Send via E-mail"].Value | ||||
|                 _onclick $"return PT.requests.view.promptBeforeEmail('{emailPrompt}')" ] [ | ||||
|                 icon "mail_outline"; rawText "  "; locStr s["Send via E-mail"] | ||||
|     [   div [ _class "pt-center-text" ] [ | ||||
|             br [] | ||||
|             a [ _class  "pt-icon-link" | ||||
|                 _href   $"/prayer-requests/print/{dtString}" | ||||
|                 _target "_blank" | ||||
|                 _title  s["View Printable"].Value ] [ | ||||
|                 icon "print"; rawText "  "; locStr s["View Printable"] | ||||
|             ] | ||||
|             if model.CanEmail then | ||||
|                 spacer | ||||
|                 if model.Date.DayOfWeek <> DayOfWeek.Sunday then | ||||
|                     let rec findSunday (date : DateTime) = | ||||
|                         if date.DayOfWeek = DayOfWeek.Sunday then date else findSunday (date.AddDays 1.) | ||||
|                     let sunday = findSunday model.Date | ||||
|                     a [ _class "pt-icon-link" | ||||
|                         _href  $"""/prayer-requests/view/{sunday.ToString "yyyy-MM-dd"}""" | ||||
|                         _title s["List for Next Sunday"].Value ] [ | ||||
|                         icon "update"; rawText "  "; locStr s["List for Next Sunday"] | ||||
|                     ] | ||||
|                     spacer | ||||
|                 let emailPrompt = s["This will e-mail the current list to every member of your group, without further prompting.  Are you sure this is what you are ready to do?"].Value | ||||
|                 a [ _class   "pt-icon-link" | ||||
|                     _href    $"/prayer-requests/email/{dtString}" | ||||
|                     _title   s["Send via E-mail"].Value | ||||
|                     _onclick $"return PT.requests.view.promptBeforeEmail('{emailPrompt}')" ] [ | ||||
|                     icon "mail_outline"; rawText "  "; locStr s["Send via E-mail"] | ||||
|                 ] | ||||
|             spacer | ||||
|             a [ _class "pt-icon-link"; _href "/prayer-requests"; _title s["Maintain Prayer Requests"].Value ] [ | ||||
|                 icon "compare_arrows"; rawText "  "; locStr s["Maintain Prayer Requests"] | ||||
|             ] | ||||
|         spacer | ||||
|         a [ _class "pt-icon-link"; _href "/prayer-requests"; _title s["Maintain Prayer Requests"].Value ] [ | ||||
|             icon "compare_arrows"; rawText "  "; locStr s["Maintain Prayer Requests"] | ||||
|         ] | ||||
|         br [] | ||||
|         rawText (model.AsHtml s) | ||||
|     ] | ||||
|     |> List.singleton | ||||
|     |> List.append [ br []; rawText (model.AsHtml s) ] | ||||
|     |> Layout.Content.standard | ||||
|     |> Layout.standard viewInfo pageTitle | ||||
|  | ||||
| @ -349,200 +349,199 @@ let preferences (model : EditPreferences) (tzs : TimeZone list) ctx viewInfo = | ||||
|             $"@media screen and (max-width: 40rem) {{ {fontsId} {{ width: 100%%; }} }}" | ||||
|         ] | ||||
|         |> AppViewInfo.withOnLoadScript "PT.smallGroup.preferences.onPageLoad" | ||||
|     form [ _action "/small-group/preferences/save"; _method "post"; _class "pt-center-columns"; Target.content ] [ | ||||
|         csrfToken ctx | ||||
|         fieldset [] [ | ||||
|             legend [] [ strong [] [ icon "date_range"; rawText "  "; locStr s["Dates"] ] ] | ||||
|             div [ _fieldRow ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.ExpireDays) ] [ locStr s["Requests Expire After"] ] | ||||
|                     span [] [ | ||||
|                         inputField "number" (nameof model.ExpireDays) (string model.ExpireDays) [ | ||||
|                             _min "1"; _max "30"; _required; _autofocus | ||||
|     [   form [ _action "/small-group/preferences/save"; _method "post"; _class "pt-center-columns"; Target.content ] [ | ||||
|             csrfToken ctx | ||||
|             fieldset [] [ | ||||
|                 legend [] [ strong [] [ icon "date_range"; rawText "  "; locStr s["Dates"] ] ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.ExpireDays) ] [ locStr s["Requests Expire After"] ] | ||||
|                         span [] [ | ||||
|                             inputField "number" (nameof model.ExpireDays) (string model.ExpireDays) [ | ||||
|                                 _min "1"; _max "30"; _required; _autofocus | ||||
|                             ] | ||||
|                             space | ||||
|                             str (s["Days"].Value.ToLower ()) | ||||
|                         ] | ||||
|                         space | ||||
|                         str (s["Days"].Value.ToLower ()) | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.DaysToKeepNew) ] [ locStr s["Requests “New” For"] ] | ||||
|                     span [] [ | ||||
|                         inputField "number" (nameof model.DaysToKeepNew) (string model.DaysToKeepNew) [ | ||||
|                             _min "1"; _max "30"; _required | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.DaysToKeepNew) ] [ locStr s["Requests “New” For"] ] | ||||
|                         span [] [ | ||||
|                             inputField "number" (nameof model.DaysToKeepNew) (string model.DaysToKeepNew) [ | ||||
|                                 _min "1"; _max "30"; _required | ||||
|                             ] | ||||
|                             space; str (s["Days"].Value.ToLower ()) | ||||
|                         ] | ||||
|                         space; str (s["Days"].Value.ToLower ()) | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.LongTermUpdateWeeks) ] [ | ||||
|                         locStr s["Long-Term Requests Alerted for Update"] | ||||
|                     ] | ||||
|                     span [] [ | ||||
|                         inputField "number" (nameof model.LongTermUpdateWeeks) (string model.LongTermUpdateWeeks) [ | ||||
|                             _min "1"; _max "30"; _required | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.LongTermUpdateWeeks) ] [ | ||||
|                             locStr s["Long-Term Requests Alerted for Update"] | ||||
|                         ] | ||||
|                         span [] [ | ||||
|                             inputField "number" (nameof model.LongTermUpdateWeeks) (string model.LongTermUpdateWeeks) [ | ||||
|                                 _min "1"; _max "30"; _required | ||||
|                             ] | ||||
|                             space; str (s["Weeks"].Value.ToLower ()) | ||||
|                         ] | ||||
|                         space; str (s["Weeks"].Value.ToLower ()) | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|         fieldset [] [ | ||||
|             legend [] [ strong [] [ icon "sort"; rawText "  "; locStr s["Request Sorting"] ] ] | ||||
|             radio (nameof model.RequestSort) $"{nameof model.RequestSort}_D" "D" model.RequestSort | ||||
|             label [ _for $"{nameof model.RequestSort}_D" ] [ locStr s["Sort by Last Updated Date"] ] | ||||
|             rawText "   " | ||||
|             radio (nameof model.RequestSort) $"{nameof model.RequestSort}_R" "R" model.RequestSort | ||||
|             label [ _for $"{nameof model.RequestSort}_R" ] [ locStr s["Sort by Requestor Name"] ] | ||||
|         ] | ||||
|         fieldset [] [ | ||||
|             legend [] [ strong [] [ icon "mail_outline"; rawText "  "; locStr s["E-mail"] ] ] | ||||
|             div [ _fieldRow ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.EmailFromName) ] [ locStr s["From Name"] ] | ||||
|                     inputField "text" (nameof model.EmailFromName) model.EmailFromName [ _required ] | ||||
|             fieldset [] [ | ||||
|                 legend [] [ strong [] [ icon "sort"; rawText "  "; locStr s["Request Sorting"] ] ] | ||||
|                 radio (nameof model.RequestSort) $"{nameof model.RequestSort}_D" "D" model.RequestSort | ||||
|                 label [ _for $"{nameof model.RequestSort}_D" ] [ locStr s["Sort by Last Updated Date"] ] | ||||
|                 rawText "   " | ||||
|                 radio (nameof model.RequestSort) $"{nameof model.RequestSort}_R" "R" model.RequestSort | ||||
|                 label [ _for $"{nameof model.RequestSort}_R" ] [ locStr s["Sort by Requestor Name"] ] | ||||
|             ] | ||||
|             fieldset [] [ | ||||
|                 legend [] [ strong [] [ icon "mail_outline"; rawText "  "; locStr s["E-mail"] ] ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.EmailFromName) ] [ locStr s["From Name"] ] | ||||
|                         inputField "text" (nameof model.EmailFromName) model.EmailFromName [ _required ] | ||||
|                     ] | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.EmailFromAddress) ] [ locStr s["From Address"] ] | ||||
|                         inputField "email" (nameof model.EmailFromAddress) model.EmailFromAddress [ _required ] | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.EmailFromAddress) ] [ locStr s["From Address"] ] | ||||
|                     inputField "email" (nameof model.EmailFromAddress) model.EmailFromAddress [ _required ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.DefaultEmailType) ] [ locStr s["E-mail Format"] ] | ||||
|                         seq { | ||||
|                             "", selectDefault s["Select"].Value | ||||
|                             yield! | ||||
|                                 ReferenceList.emailTypeList HtmlFormat s | ||||
|                                 |> Seq.skip 1 | ||||
|                                 |> Seq.map (fun typ -> fst typ, (snd typ).Value) | ||||
|                         } | ||||
|                         |> selectList (nameof model.DefaultEmailType) model.DefaultEmailType [ _required ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|             div [ _fieldRow ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.DefaultEmailType) ] [ locStr s["E-mail Format"] ] | ||||
|                     seq { | ||||
|                         "", selectDefault s["Select"].Value | ||||
|                         yield! | ||||
|                             ReferenceList.emailTypeList HtmlFormat s | ||||
|                             |> Seq.skip 1 | ||||
|                             |> Seq.map (fun typ -> fst typ, (snd typ).Value) | ||||
|                     } | ||||
|                     |> selectList (nameof model.DefaultEmailType) model.DefaultEmailType [ _required ] | ||||
|             fieldset [] [ | ||||
|                 legend [] [ strong [] [ icon "color_lens"; rawText "  "; locStr s["Colors"] ]; rawText " ***" ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _class "pt-center-text" ] [ locStr s["Color of Heading Lines"] ] | ||||
|                         span [] [ | ||||
|                             radio (nameof model.LineColorType) $"{nameof model.LineColorType}_Name" "Name" | ||||
|                                   model.LineColorType | ||||
|                             label [ _for $"{nameof model.LineColorType}_Name" ] [ locStr s["Named Color"] ] | ||||
|                             namedColorList (nameof model.LineColor) model.LineColor [ | ||||
|                                 _id $"{nameof model.LineColor}_Select" | ||||
|                                 if model.LineColor.StartsWith "#" then _disabled ] s | ||||
|                             rawText "    "; str (s["or"].Value.ToUpper ()) | ||||
|                             radio (nameof model.LineColorType) $"{nameof model.LineColorType}_RGB" "RGB" | ||||
|                                    model.LineColorType | ||||
|                             label [ _for $"{nameof model.LineColorType}_RGB" ] [ locStr s["Custom Color"] ] | ||||
|                             input [ _type  "color"  | ||||
|                                     _name  (nameof model.LineColor) | ||||
|                                     _id    $"{nameof model.LineColor}_Color" | ||||
|                                     _value model.LineColor // TODO: convert to hex or skip if named | ||||
|                                     if not (model.LineColor.StartsWith "#") then _disabled ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _class "pt-center-text" ] [ locStr s["Color of Heading Text"] ] | ||||
|                         span [] [ | ||||
|                             radio (nameof model.HeadingColorType) $"{nameof model.HeadingColorType}_Name" "Name" | ||||
|                                   model.HeadingColorType | ||||
|                             label [ _for $"{nameof model.HeadingColorType}_Name" ] [ locStr s["Named Color"] ] | ||||
|                             namedColorList (nameof model.HeadingColor) model.HeadingColor [ | ||||
|                                 _id $"{nameof model.HeadingColor}_Select" | ||||
|                                 if model.HeadingColor.StartsWith "#" then _disabled ] s | ||||
|                             rawText "    "; str (s["or"].Value.ToUpper ()) | ||||
|                             radio (nameof model.HeadingColorType) $"{nameof model.HeadingColorType}_RGB" "RGB" | ||||
|                                   model.HeadingColorType | ||||
|                             label [ _for $"{nameof model.HeadingColorType}_RGB" ] [ locStr s["Custom Color"] ] | ||||
|                             input [ _type  "color" | ||||
|                                     _name  (nameof model.HeadingColor) | ||||
|                                     _id    $"{nameof model.HeadingColor}_Color" | ||||
|                                     _value model.HeadingColor // TODO: convert to hex or skip if named | ||||
|                                     if not (model.HeadingColor.StartsWith "#") then _disabled ] | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|         fieldset [] [ | ||||
|             legend [] [ strong [] [ icon "color_lens"; rawText "  "; locStr s["Colors"] ]; rawText " ***" ] | ||||
|             div [ _fieldRow ] [ | ||||
|             fieldset [] [ | ||||
|                 legend [] [ strong [] [ icon "font_download"; rawText "  "; locStr s["Fonts"] ] ] | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _class "pt-center-text" ] [ locStr s["Color of Heading Lines"] ] | ||||
|                     label [ _for (nameof model.Fonts) ] [ locStr s["Fonts** for List"] ] | ||||
|                     inputField "text" (nameof model.Fonts) model.Fonts [ _required ] | ||||
|                 ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.HeadingFontSize) ] [ locStr s["Heading Text Size"] ] | ||||
|                         inputField "number" (nameof model.HeadingFontSize) (string model.HeadingFontSize) [ | ||||
|                             _min "8"; _max "24"; _required | ||||
|                         ] | ||||
|                     ] | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.ListFontSize) ] [ locStr s["List Text Size"] ] | ||||
|                         inputField "number" (nameof model.ListFontSize) (string model.ListFontSize) [ | ||||
|                             _min "8"; _max "24"; _required | ||||
|                         ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|             fieldset [] [ | ||||
|                 legend [] [ strong [] [ icon "settings"; rawText "  "; locStr s["Other Settings"] ] ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.TimeZone) ] [ locStr s["Time Zone"] ] | ||||
|                         seq { | ||||
|                             "", selectDefault s["Select"].Value | ||||
|                             yield! | ||||
|                                 tzs | ||||
|                                 |> List.map (fun tz -> | ||||
|                                     TimeZoneId.toString tz.Id, (TimeZones.name tz.Id s).Value) | ||||
|                         } | ||||
|                         |> selectList (nameof model.TimeZone) model.TimeZone [ _required ] | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _inputField ] [ | ||||
|                     label [] [ locStr s["Request List Visibility"] ] | ||||
|                     span [] [ | ||||
|                         radio (nameof model.LineColorType) $"{nameof model.LineColorType}_Name" "Name" | ||||
|                               model.LineColorType | ||||
|                         label [ _for $"{nameof model.LineColorType}_Name" ] [ locStr s["Named Color"] ] | ||||
|                         namedColorList (nameof model.LineColor) model.LineColor [ | ||||
|                             _id $"{nameof model.LineColor}_Select" | ||||
|                             if model.LineColor.StartsWith "#" then _disabled ] s | ||||
|                         rawText "    "; str (s["or"].Value.ToUpper ()) | ||||
|                         radio (nameof model.LineColorType) $"{nameof model.LineColorType}_RGB" "RGB" model.LineColorType | ||||
|                         label [ _for $"{nameof model.LineColorType}_RGB" ] [ locStr s["Custom Color"] ] | ||||
|                         input [ _type  "color"  | ||||
|                                 _name  (nameof model.LineColor) | ||||
|                                 _id    $"{nameof model.LineColor}_Color" | ||||
|                                 _value model.LineColor // TODO: convert to hex or skip if named | ||||
|                                 if not (model.LineColor.StartsWith "#") then _disabled ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|             div [ _fieldRow ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _class "pt-center-text" ] [ locStr s["Color of Heading Text"] ] | ||||
|                     span [] [ | ||||
|                         radio (nameof model.HeadingColorType) $"{nameof model.HeadingColorType}_Name" "Name" | ||||
|                               model.HeadingColorType | ||||
|                         label [ _for $"{nameof model.HeadingColorType}_Name" ] [ locStr s["Named Color"] ] | ||||
|                         namedColorList (nameof model.HeadingColor) model.HeadingColor [ | ||||
|                             _id $"{nameof model.HeadingColor}_Select" | ||||
|                             if model.HeadingColor.StartsWith "#" then _disabled ] s | ||||
|                         rawText "    "; str (s["or"].Value.ToUpper ()) | ||||
|                         radio (nameof model.HeadingColorType) $"{nameof model.HeadingColorType}_RGB" "RGB" | ||||
|                               model.HeadingColorType | ||||
|                         label [ _for $"{nameof model.HeadingColorType}_RGB" ] [ locStr s["Custom Color"] ] | ||||
|                         input [ _type  "color" | ||||
|                                 _name  (nameof model.HeadingColor) | ||||
|                                 _id    $"{nameof model.HeadingColor}_Color" | ||||
|                                 _value model.HeadingColor // TODO: convert to hex or skip if named | ||||
|                                 if not (model.HeadingColor.StartsWith "#") then _disabled ] | ||||
|                         let name  = nameof model.Visibility | ||||
|                         let value = string model.Visibility | ||||
|                         radio name $"{name}_Public" (string GroupVisibility.PublicList) value | ||||
|                         label [ _for $"{name}_Public" ] [ locStr s["Public"] ] | ||||
|                         rawText "  " | ||||
|                         radio name $"{name}_Private" (string GroupVisibility.PrivateList) value | ||||
|                         label [ _for $"{name}_Private" ] [ locStr s["Private"] ] | ||||
|                         rawText "  " | ||||
|                         radio name $"{name}_Password" (string GroupVisibility.HasPassword) value | ||||
|                         label [ _for $"{name}_Password" ] [ locStr s["Password Protected"] ] | ||||
|                     ] | ||||
|                 ] | ||||
|                 let classSuffix = if model.Visibility = GroupVisibility.HasPassword then [ "pt-show" ] else [] | ||||
|                 div [ _id "divClassPassword"; _fieldRowWith ("pt-fadeable" :: classSuffix) ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.GroupPassword) ] [ locStr s["Group Password (Used to Read Online)"] ] | ||||
|                         inputField "text" (nameof model.GroupPassword) (defaultArg model.GroupPassword "") [] | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _fieldRow ] [ | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.PageSize) ] [ locStr s["Page Size"] ] | ||||
|                         inputField "number" (nameof model.PageSize) (string model.PageSize) [ | ||||
|                             _min "10"; _max "255"; _required | ||||
|                         ] | ||||
|                     ] | ||||
|                     div [ _inputField ] [ | ||||
|                         label [ _for (nameof model.AsOfDate) ] [ locStr s["“As of” Date Display"] ] | ||||
|                         ReferenceList.asOfDateList s | ||||
|                         |> List.map (fun (code, desc) -> code, desc.Value) | ||||
|                         |> selectList (nameof model.AsOfDate) model.AsOfDate [ _required ] | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|             div [ _fieldRow ] [ submit [] "save" s["Save Preferences"] ] | ||||
|         ] | ||||
|         fieldset [] [ | ||||
|             legend [] [ strong [] [ icon "font_download"; rawText "  "; locStr s["Fonts"] ] ] | ||||
|             div [ _inputField ] [ | ||||
|                 label [ _for (nameof model.Fonts) ] [ locStr s["Fonts** for List"] ] | ||||
|                 inputField "text" (nameof model.Fonts) model.Fonts [ _required ] | ||||
|             ] | ||||
|             div [ _fieldRow ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.HeadingFontSize) ] [ locStr s["Heading Text Size"] ] | ||||
|                     inputField "number" (nameof model.HeadingFontSize) (string model.HeadingFontSize) [ | ||||
|                         _min "8"; _max "24"; _required | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.ListFontSize) ] [ locStr s["List Text Size"] ] | ||||
|                     inputField "number" (nameof model.ListFontSize) (string model.ListFontSize) [ | ||||
|                         _min "8"; _max "24"; _required | ||||
|                     ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|         fieldset [] [ | ||||
|             legend [] [ strong [] [ icon "settings"; rawText "  "; locStr s["Other Settings"] ] ] | ||||
|             div [ _fieldRow ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.TimeZone) ] [ locStr s["Time Zone"] ] | ||||
|                     seq { | ||||
|                         "", selectDefault s["Select"].Value | ||||
|                         yield! | ||||
|                             tzs | ||||
|                             |> List.map (fun tz -> | ||||
|                                 TimeZoneId.toString tz.Id, (TimeZones.name tz.Id s).Value) | ||||
|                     } | ||||
|                     |> selectList (nameof model.TimeZone) model.TimeZone [ _required ] | ||||
|                 ] | ||||
|             ] | ||||
|             div [ _inputField ] [ | ||||
|                 label [] [ locStr s["Request List Visibility"] ] | ||||
|                 span [] [ | ||||
|                     let name  = nameof model.Visibility | ||||
|                     let value = string model.Visibility | ||||
|                     radio name $"{name}_Public" (string RequestVisibility.``public``) value | ||||
|                     label [ _for $"{name}_Public" ] [ locStr s["Public"] ] | ||||
|                     rawText "  " | ||||
|                     radio name $"{name}_Private" (string RequestVisibility.``private``) value | ||||
|                     label [ _for $"{name}_Private" ] [ locStr s["Private"] ] | ||||
|                     rawText "  " | ||||
|                     radio name $"{name}_Password" (string RequestVisibility.passwordProtected) value | ||||
|                     label [ _for $"{name}_Password" ] [ locStr s["Password Protected"] ] | ||||
|                 ] | ||||
|             ] | ||||
|             let classSuffix = if model.Visibility = RequestVisibility.passwordProtected then [ "pt-show" ] else [] | ||||
|             div [ _id "divClassPassword"; _fieldRowWith ("pt-fadeable" :: classSuffix) ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.GroupPassword) ] [ locStr s["Group Password (Used to Read Online)"] ] | ||||
|                     inputField "text" (nameof model.GroupPassword) (defaultArg model.GroupPassword "") [] | ||||
|                 ] | ||||
|             ] | ||||
|             div [ _fieldRow ] [ | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.PageSize) ] [ locStr s["Page Size"] ] | ||||
|                     inputField "number" (nameof model.PageSize) (string model.PageSize) [ | ||||
|                         _min "10"; _max "255"; _required | ||||
|                     ] | ||||
|                 ] | ||||
|                 div [ _inputField ] [ | ||||
|                     label [ _for (nameof model.AsOfDate) ] [ locStr s["“As of” Date Display"] ] | ||||
|                     ReferenceList.asOfDateList s | ||||
|                     |> List.map (fun (code, desc) -> code, desc.Value) | ||||
|                     |> selectList (nameof model.AsOfDate) model.AsOfDate [ _required ] | ||||
|                 ] | ||||
|             ] | ||||
|         ] | ||||
|         div [ _fieldRow ] [ submit [] "save" s["Save Preferences"] ] | ||||
|     ] | ||||
|     |> List.singleton | ||||
|     |> List.append [ | ||||
|         p [] [ | ||||
|             rawText "** " | ||||
|             raw l["List font names, separated by commas."] | ||||
|  | ||||
| @ -199,7 +199,7 @@ let maintain (users : User list) ctx viewInfo = | ||||
|                     let userId    = shortGuid user.Id.Value | ||||
|                     let delAction = $"/user/{userId}/delete" | ||||
|                     let delPrompt = s["Are you sure you want to delete this {0}?  This action cannot be undone.", | ||||
|                                       $"""{s["User"].Value.ToLower ()} ({user.fullName})"""].Value | ||||
|                                       $"""{s["User"].Value.ToLower ()} ({user.Name})"""].Value | ||||
|                     tr [] [ | ||||
|                         td [] [ | ||||
|                             a [ _href $"/user/{userId}/edit"; _title s["Edit This User"].Value ] [ icon "edit" ] | ||||
| @ -212,7 +212,7 @@ let maintain (users : User list) ctx viewInfo = | ||||
|                                 icon "delete_forever" | ||||
|                             ] | ||||
|                         ] | ||||
|                         td [] [ str user.fullName ] | ||||
|                         td [] [ str user.Name ] | ||||
|                         td [ _class "pt-center-text" ] [ | ||||
|                             if user.IsAdmin then strong [] [ locStr s["Yes"] ] else locStr s["No"] | ||||
|                         ] | ||||
|  | ||||
| @ -175,19 +175,19 @@ module Key = | ||||
| 
 | ||||
| 
 | ||||
| /// Enumerated values for small group request list visibility (derived from preferences, used in UI) | ||||
| module RequestVisibility = | ||||
| module GroupVisibility = | ||||
|      | ||||
|     /// Requests are publicly accessible | ||||
|     [<Literal>] | ||||
|     let ``public`` = 1 | ||||
|     let PublicList = 1 | ||||
|      | ||||
|     /// The small group members can enter a password to view the request list | ||||
|     [<Literal>] | ||||
|     let passwordProtected = 2 | ||||
|     let HasPassword = 2 | ||||
|      | ||||
|     /// No one can see the requests for a small group except its administrators ("User" access level) | ||||
|     [<Literal>] | ||||
|     let ``private`` = 3 | ||||
|     let PrivateList = 3 | ||||
| 
 | ||||
| 
 | ||||
| /// Links for help locations | ||||
|  | ||||
| @ -124,9 +124,6 @@ type AppViewInfo = | ||||
|     {   /// CSS files for the page | ||||
|         Style : string list | ||||
|          | ||||
|         /// JavaScript files for the page | ||||
|         Script : string list | ||||
|          | ||||
|         /// The link for help on this page | ||||
|         HelpLink : string option | ||||
|          | ||||
| @ -162,7 +159,6 @@ module AppViewInfo = | ||||
|     /// A fresh version that can be populated to process the current request | ||||
|     let fresh = | ||||
|         {   Style        = [] | ||||
|             Script       = [] | ||||
|             HelpLink     = None | ||||
|             Messages     = [] | ||||
|             Version      = "" | ||||
| @ -224,7 +220,7 @@ module AssignGroups = | ||||
|     /// Create an instance of this form from an existing user | ||||
|     let fromUser (user : User) = | ||||
|         {   UserId      = shortGuid user.Id.Value | ||||
|             UserName    = user.fullName | ||||
|             UserName    = user.Name | ||||
|             SmallGroups = "" | ||||
|         } | ||||
| 
 | ||||
| @ -275,7 +271,7 @@ with | ||||
|             Name             = this.Name | ||||
|             City             = this.City | ||||
|             State            = this.State | ||||
|             HasInterface     = match this.HasInterface with Some x -> x | None -> false | ||||
|             HasVpsInterface  = match this.HasInterface with Some x -> x | None -> false | ||||
|             InterfaceAddress = match this.HasInterface with Some x when x -> this.InterfaceAddress | _ -> None | ||||
|         } | ||||
| 
 | ||||
| @ -288,7 +284,7 @@ module EditChurch = | ||||
|             Name             = church.Name | ||||
|             City             = church.City | ||||
|             State            = church.State | ||||
|             HasInterface     = match church.HasInterface with true -> Some true | false -> None | ||||
|             HasInterface     = match church.HasVpsInterface with true -> Some true | false -> None | ||||
|             InterfaceAddress = church.InterfaceAddress | ||||
|         } | ||||
|      | ||||
| @ -408,11 +404,9 @@ with | ||||
|     /// Set the properties of a small group based on the form's properties | ||||
|     member this.PopulatePreferences (prefs : ListPreferences) = | ||||
|         let isPublic, grpPw = | ||||
|             match this.Visibility with | ||||
|             | RequestVisibility.``public`` -> true, "" | ||||
|             | RequestVisibility.passwordProtected -> false, (defaultArg this.GroupPassword "") | ||||
|             | RequestVisibility.``private`` | ||||
|             | _ -> false, "" | ||||
|             if   this.Visibility = GroupVisibility.PublicList  then true, "" | ||||
|             elif this.Visibility = GroupVisibility.HasPassword then false, (defaultArg this.GroupPassword "") | ||||
|             else (* GroupVisibility.PrivateList *) false, "" | ||||
|         { prefs with | ||||
|             DaysToExpire        = this.ExpireDays | ||||
|             DaysToKeepNew       = this.DaysToKeepNew | ||||
| @ -457,10 +451,9 @@ module EditPreferences = | ||||
|             PageSize            = prefs.PageSize | ||||
|             AsOfDate            = AsOfDateDisplay.toCode prefs.AsOfDateDisplay | ||||
|             Visibility          = | ||||
|                 match true with  | ||||
|                 | _ when prefs.IsPublic -> RequestVisibility.``public`` | ||||
|                 | _ when prefs.GroupPassword = "" -> RequestVisibility.``private`` | ||||
|                 | _ -> RequestVisibility.passwordProtected | ||||
|                 if   prefs.IsPublic           then GroupVisibility.PublicList | ||||
|                 elif prefs.GroupPassword = "" then GroupVisibility.PrivateList | ||||
|                 else                               GroupVisibility.HasPassword | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,10 +1,7 @@ | ||||
| module PrayerTracker.Handlers.PrayerRequest | ||||
| 
 | ||||
| open System | ||||
| open System.Threading.Tasks | ||||
| open Giraffe | ||||
| open Microsoft.AspNetCore.Http | ||||
| open NodaTime | ||||
| open PrayerTracker | ||||
| open PrayerTracker.Entities | ||||
| open PrayerTracker.ViewModels | ||||
| @ -20,11 +17,13 @@ let private findRequest (ctx : HttpContext) reqId = task { | ||||
|     | None -> return Result.Error fourOhFour | ||||
| } | ||||
| 
 | ||||
| open NodaTime | ||||
| 
 | ||||
| /// Generate a list of requests for the given date | ||||
| let private generateRequestList ctx date = task { | ||||
|     let  grp      = currentGroup ctx | ||||
|     let  clock    = ctx.GetService<IClock> () | ||||
|     let  listDate = match date with Some d -> d | None -> grp.localDateNow clock | ||||
|     let  listDate = match date with Some d -> d | None -> grp.LocalDateNow clock | ||||
|     let! reqs     = ctx.db.AllRequestsForSmallGroup grp clock (Some listDate) true 0 | ||||
|     return | ||||
|         {   Requests   = reqs | ||||
| @ -36,29 +35,30 @@ let private generateRequestList ctx date = task { | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| open System | ||||
| 
 | ||||
| /// Parse a string into a date (optionally, of course) | ||||
| let private parseListDate (date : string option) = | ||||
|     match date with | ||||
|     | Some dt -> match DateTime.TryParse dt with true, d -> Some d | false, _ -> None | ||||
|     | None -> None | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-request/[request-id]/edit | ||||
| let edit reqId : HttpHandler = requireAccess [ User ] >=> fun next ctx -> task { | ||||
|     let startTicks = DateTime.Now.Ticks | ||||
|     let grp        = currentGroup ctx | ||||
|     let now        = grp.localDateNow (ctx.GetService<IClock> ()) | ||||
|     let now        = grp.LocalDateNow (ctx.GetService<IClock> ()) | ||||
|     let requestId  = PrayerRequestId reqId | ||||
|     if requestId.Value = Guid.Empty then | ||||
|         return! | ||||
|             { viewInfo ctx startTicks with Script = [ "ckeditor/ckeditor" ]; HelpLink = Some Help.editRequest } | ||||
|             { viewInfo ctx startTicks with HelpLink = Some Help.editRequest } | ||||
|             |> Views.PrayerRequest.edit EditRequest.empty (now.ToString "yyyy-MM-dd") ctx | ||||
|             |> renderHtml next ctx | ||||
|     else | ||||
|         match! findRequest ctx requestId with | ||||
|         | Ok req -> | ||||
|             let s = Views.I18N.localizer.Force () | ||||
|             if req.isExpired now grp.Preferences.DaysToExpire then | ||||
|             if req.IsExpired now grp.Preferences.DaysToExpire then | ||||
|                 { UserMessage.warning with | ||||
|                     Text        = htmlLocString s["This request is expired."] | ||||
|                     Description = | ||||
| @ -68,13 +68,12 @@ let edit reqId : HttpHandler = requireAccess [ User ] >=> fun next ctx -> task { | ||||
|                   } | ||||
|                 |> addUserMessage ctx | ||||
|             return! | ||||
|                 { viewInfo ctx startTicks with Script = [ "ckeditor/ckeditor" ]; HelpLink = Some Help.editRequest } | ||||
|                 { viewInfo ctx startTicks with HelpLink = Some Help.editRequest } | ||||
|                 |> Views.PrayerRequest.edit (EditRequest.fromRequest req) "" ctx | ||||
|                 |> renderHtml next ctx | ||||
|         | Result.Error e -> return! e next ctx | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-requests/email/[date] | ||||
| let email date : HttpHandler = requireAccess [ User ] >=> fun next ctx -> task { | ||||
|     let  startTicks  = DateTime.Now.Ticks | ||||
| @ -93,7 +92,6 @@ let email date : HttpHandler = requireAccess [ User ] >=> fun next ctx -> task { | ||||
|         |> renderHtml next ctx | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// POST /prayer-request/[request-id]/delete | ||||
| let delete reqId : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> fun next ctx -> task { | ||||
|     let requestId = PrayerRequestId reqId | ||||
| @ -107,7 +105,6 @@ let delete reqId : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> fun | ||||
|     | Result.Error e -> return! e next ctx | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-request/[request-id]/expire | ||||
| let expire reqId : HttpHandler = requireAccess [ User ] >=> fun next ctx -> task { | ||||
|     let requestId = PrayerRequestId reqId | ||||
| @ -121,7 +118,6 @@ let expire reqId : HttpHandler = requireAccess [ User ] >=> fun next ctx -> task | ||||
|     | Result.Error e -> return! e next ctx | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-requests/[group-id]/list | ||||
| let list groupId : HttpHandler = requireAccess [ AccessLevel.Public ] >=> fun next ctx -> task { | ||||
|     let startTicks = DateTime.Now.Ticks | ||||
| @ -132,12 +128,12 @@ let list groupId : HttpHandler = requireAccess [ AccessLevel.Public ] >=> fun ne | ||||
|         return! | ||||
|             viewInfo ctx startTicks | ||||
|             |> Views.PrayerRequest.list | ||||
|                 { Requests   = reqs | ||||
|                   Date       = grp.localDateNow clock | ||||
|                   SmallGroup = grp | ||||
|                   ShowHeader = true | ||||
|                   CanEmail   = Option.isSome ctx.Session.user | ||||
|                   Recipients = [] | ||||
|                 {   Requests   = reqs | ||||
|                     Date       = grp.LocalDateNow clock | ||||
|                     SmallGroup = grp | ||||
|                     ShowHeader = true | ||||
|                     CanEmail   = Option.isSome ctx.Session.user | ||||
|                     Recipients = [] | ||||
|                 } | ||||
|             |> renderHtml next ctx | ||||
|     | Some _ -> | ||||
| @ -147,7 +143,6 @@ let list groupId : HttpHandler = requireAccess [ AccessLevel.Public ] >=> fun ne | ||||
|     | None -> return! fourOhFour next ctx | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-requests/lists | ||||
| let lists : HttpHandler = requireAccess [ AccessLevel.Public ] >=> fun next ctx -> task { | ||||
|     let  startTicks = DateTime.Now.Ticks | ||||
| @ -158,7 +153,6 @@ let lists : HttpHandler = requireAccess [ AccessLevel.Public ] >=> fun next ctx | ||||
|         |> renderHtml next ctx | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-requests[/inactive?] | ||||
| ///  - OR - | ||||
| /// GET /prayer-requests?search=[search-query] | ||||
| @ -201,8 +195,6 @@ let print date : HttpHandler = requireAccess [ User; Group ] >=> fun next ctx -> | ||||
|         Views.PrayerRequest.print list appVersion | ||||
|         |> renderHtml next ctx | ||||
| } | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-request/[request-id]/restore | ||||
| let restore reqId : HttpHandler = requireAccess [ User ] >=> fun next ctx -> task { | ||||
| @ -217,6 +209,7 @@ let restore reqId : HttpHandler = requireAccess [ User ] >=> fun next ctx -> tas | ||||
|     | Result.Error e -> return! e next ctx | ||||
| } | ||||
| 
 | ||||
| open System.Threading.Tasks | ||||
| 
 | ||||
| /// POST /prayer-request/save | ||||
| let save : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> fun next ctx -> task { | ||||
| @ -235,7 +228,7 @@ let save : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> fun next ct | ||||
|                     Expiration  = Expiration.fromCode m.Expiration | ||||
|                 } | ||||
|             let grp = currentGroup ctx | ||||
|             let now = grp.localDateNow (ctx.GetService<IClock> ()) | ||||
|             let now = grp.LocalDateNow (ctx.GetService<IClock> ()) | ||||
|             match m.IsNew with | ||||
|             | true -> | ||||
|                 let dt = defaultArg m.EnteredDate now | ||||
| @ -257,7 +250,6 @@ let save : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> fun next ct | ||||
|     | Result.Error e -> return! bindError e next ctx | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// GET /prayer-request/view/[date?] | ||||
| let view date : HttpHandler = requireAccess [ User; Group ] >=> fun next ctx -> task { | ||||
|     let  startTicks = DateTime.Now.Ticks | ||||
|  | ||||
| @ -16,7 +16,7 @@ let private setGroupCookie (ctx : HttpContext) pwHash = | ||||
| 
 | ||||
| /// GET /small-group/announcement | ||||
| let announcement : HttpHandler = requireAccess [ User ] >=> fun next ctx -> | ||||
|     { viewInfo ctx DateTime.Now.Ticks with HelpLink = Some Help.sendAnnouncement; Script = [ "ckeditor/ckeditor" ] } | ||||
|     { viewInfo ctx DateTime.Now.Ticks with HelpLink = Some Help.sendAnnouncement } | ||||
|     |> Views.SmallGroup.announcement (currentUser ctx).IsAdmin ctx | ||||
|     |> renderHtml next ctx | ||||
| 
 | ||||
| @ -266,7 +266,7 @@ let sendAnnouncement : HttpHandler = requireAccess [ User ] >=> validateCsrf >=> | ||||
|     | Ok m -> | ||||
|         let grp = currentGroup ctx | ||||
|         let usr = currentUser ctx | ||||
|         let now = grp.localTimeNow (ctx.GetService<IClock> ()) | ||||
|         let now = grp.LocalTimeNow (ctx.GetService<IClock> ()) | ||||
|         let s   = Views.I18N.localizer.Force () | ||||
|         // Reformat the text to use the class's font stylings | ||||
|         let requestText = ckEditorToText m.Text | ||||
|  | ||||
| @ -85,7 +85,7 @@ let delete usrId : HttpHandler = requireAccess [ Admin ] >=> validateCsrf >=> fu | ||||
|         ctx.db.RemoveEntry user | ||||
|         let! _ = ctx.db.SaveChangesAsync () | ||||
|         let  s = Views.I18N.localizer.Force () | ||||
|         addInfo ctx s["Successfully deleted user {0}", user.fullName] | ||||
|         addInfo ctx s["Successfully deleted user {0}", user.Name] | ||||
|         return! redirectTo false "/users" next ctx | ||||
|     | _ -> return! fourOhFour next ctx | ||||
| } | ||||
| @ -220,10 +220,9 @@ let save : HttpHandler = requireAccess [ Admin ] >=> validateCsrf >=> fun next c | ||||
|             if m.IsNew then | ||||
|                 let h = CommonFunctions.htmlString | ||||
|                 { UserMessage.info with | ||||
|                     Text = h s["Successfully {0} user", s["Added"].Value.ToLower ()] | ||||
|                     Text        = h s["Successfully {0} user", s["Added"].Value.ToLower ()] | ||||
|                     Description =  | ||||
|                       h s["Please select at least one group for which this user ({0}) is authorized", | ||||
|                           updatedUser.fullName] | ||||
|                       h s["Please select at least one group for which this user ({0}) is authorized", updatedUser.Name] | ||||
|                       |> Some | ||||
|                 } | ||||
|                 |> addUserMessage ctx | ||||
|  | ||||
| @ -1,10 +1,18 @@ | ||||
| /** | ||||
|  * This is the main stylesheet for the PrayerTracker application. | ||||
|  */ | ||||
| :root { | ||||
|   --dark-blue-hue: 240; | ||||
|   --dark-blue-sat: 100%; | ||||
|   --darkest: hsl(var(--dark-blue-hue), var(--dark-blue-sat), 6%); | ||||
|   --dark: hsl(var(--dark-blue-hue), var(--dark-blue-sat), 13%); | ||||
|   --lighter-dark: hsl(var(--dark-blue-hue), var(--dark-blue-sat), 25%); | ||||
|   --inverse-backgroud: hsl(0, 0%, 95%); | ||||
|   --background: hsla(0, 0%, 0%, .01); | ||||
| } | ||||
| body { | ||||
|   background-color: #222; | ||||
|   background-color: var(--background); | ||||
|   margin: 0; | ||||
|   margin-bottom: 25px; | ||||
|   font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; | ||||
|   font-size: 1rem; | ||||
| } | ||||
| @ -18,10 +26,10 @@ a, | ||||
| a:link, | ||||
| a:visited { | ||||
|   text-decoration: none; | ||||
|   color: navy; | ||||
|   color: var(--dark); | ||||
| } | ||||
| a:hover { | ||||
|   border-bottom: dotted 1px navy; | ||||
|   border-bottom: dotted 1px var(--darkest); | ||||
| }  | ||||
| a > img { | ||||
|   border: 0; | ||||
| @ -32,7 +40,7 @@ a > img { | ||||
|   justify-content: space-between; | ||||
|   overflow: hidden; | ||||
|   width: 100%; | ||||
|   background-image: linear-gradient(to bottom, #222, #444); | ||||
|   background-image: linear-gradient(to bottom, var(--darkest), var(--dark)); | ||||
|   margin-bottom: 0; | ||||
| } | ||||
| .pt-title-bar-left, | ||||
| @ -46,7 +54,7 @@ a > img { | ||||
|   float: left; | ||||
|   font-size: 1.25rem; | ||||
|   font-weight: bold; | ||||
|   padding: .5rem 1rem 0 1rem; | ||||
|   padding: .5rem 1rem 0 .75rem; | ||||
| } | ||||
| .pt-title-bar-home a:link, | ||||
| .pt-title-bar-home a:visited { | ||||
| @ -87,7 +95,7 @@ a > img { | ||||
| .pt-title-bar .dropdown-content { | ||||
|   display: none; | ||||
|   position: absolute; | ||||
|   background-image: linear-gradient(to bottom, #444, #888); | ||||
|   background-image: linear-gradient(to bottom, var(--dark), var(--lighter-dark)); | ||||
|   min-width: 160px; | ||||
|   box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); | ||||
|   z-index: 1; | ||||
| @ -100,14 +108,14 @@ a > img { | ||||
|   text-align: left; | ||||
| } | ||||
| .pt-title-bar .dropdown-content a:hover { | ||||
|   background-color: #222; | ||||
|   background-color: var(--inverse-backgroud); | ||||
|   color: var(--lighter-dark); | ||||
| } | ||||
| .pt-title-bar .dropdown:hover .dropdown-content { | ||||
|   display: block; | ||||
| } | ||||
| #pt-body { | ||||
|   background-color: #fcfcfc; | ||||
|   padding-bottom: 10px; | ||||
|   padding-bottom: 1rem; | ||||
| } | ||||
| #pt-language { | ||||
|   background-color: lightgray; | ||||
| @ -116,31 +124,31 @@ a > img { | ||||
|   justify-content: space-between; | ||||
|   border-bottom: solid 1px darkgray; | ||||
|   border-top: solid 1px darkgray; | ||||
|   padding: 0 .75rem; | ||||
| } | ||||
| #pt-page-title { | ||||
|   text-align: center; | ||||
|   border-bottom: dotted 1px lightgray; | ||||
| } | ||||
| .pt-content { | ||||
|   margin: auto; | ||||
|   margin: auto auto 1.5rem auto; | ||||
|   max-width: 60rem; | ||||
| } | ||||
| .pt-content.pt-full-width { | ||||
|   max-width: unset; | ||||
|   margin-left: .5%; | ||||
|   margin-right: .5%; | ||||
|   margin-left: .75rem; | ||||
|   margin-right: .75rem; | ||||
| } | ||||
| @media screen and (max-width: 60rem) { | ||||
|   .pt-content { | ||||
|     margin-left: .5%; | ||||
|     margin-right: .5%; | ||||
|     margin-left: .75rem; | ||||
|     margin-right: .75rem; | ||||
|   } | ||||
| } | ||||
| fieldset { | ||||
|   margin: auto; | ||||
|   margin: auto auto 1rem auto; | ||||
|   border: solid 1px #ccc; | ||||
|   border-radius: 1rem; | ||||
|   margin-bottom: 1rem; | ||||
| } | ||||
| input[type=email], | ||||
| input[type=text], | ||||
| @ -148,7 +156,8 @@ input[type=password], | ||||
| input[type=date], | ||||
| input[type=number], | ||||
| select { | ||||
|   border-radius: 5px; | ||||
|   border-radius: .25rem; | ||||
|   border-color: var(--lighter-dark); | ||||
|   font-size: 1rem; | ||||
|   padding: .2rem; | ||||
|   font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; | ||||
| @ -160,30 +169,40 @@ button[type=submit] { | ||||
|   border-radius: 10px; | ||||
|   padding: .2rem 1rem; | ||||
|   margin-top: .5rem; | ||||
|   background-color: #444; | ||||
|   border: none; | ||||
|   background-color: var(--lighter-dark); | ||||
|   border: solid 1px var(--lighter-dark); | ||||
|   color: white; | ||||
| } | ||||
| button[type=submit]:hover { | ||||
|   background-color: #222; | ||||
|   cursor:pointer; | ||||
|   color: var(--lighter-dark); | ||||
|   background-color: var(--inverse-backgroud); | ||||
|   cursor: pointer; | ||||
| } | ||||
| footer { | ||||
| footer.pt-footer { | ||||
|   position: fixed; | ||||
|   bottom: 0; | ||||
|   width: 100%; | ||||
|   border-bottom: solid 10px #222; | ||||
|   padding-top: .5rem; | ||||
|   background-image: linear-gradient(to bottom, var(--background), var(--darkest)); | ||||
|   display: flex; | ||||
|   flex-flow: row wrap; | ||||
|   justify-content: space-between; | ||||
|   align-items: end; | ||||
| } | ||||
| #pt-legal { | ||||
|   background-color: #222; | ||||
|   margin: 0 0 -30px 0; | ||||
|   padding-left: 10px; | ||||
|   padding-left: .75rem; | ||||
| } | ||||
| #pt-legal a:link, | ||||
| #pt-legal a:visited { | ||||
|   color: lightgray; | ||||
|   color: rgba(255, 255, 255, .5); | ||||
|   color: white; | ||||
|   font-size: 10pt; | ||||
|   background-color: var(--darkest); | ||||
|   padding: 0 .5rem; | ||||
|   border-top-left-radius: .5rem; | ||||
|   border-top-right-radius: .5rem; | ||||
| } | ||||
| #pt-legal a:hover { | ||||
|   background-color: var(--lighter-dark); | ||||
| } | ||||
| #pt-footer { | ||||
|   border: solid 2px navy; | ||||
| @ -191,12 +210,10 @@ footer { | ||||
|   border-top-left-radius: 7px; | ||||
|   border-top-right-radius: 7px; | ||||
|   padding: 2px 5px 0 5px; | ||||
|   margin: 0 10px -11px auto; | ||||
|   margin-right: .75rem; | ||||
|   font-size: 70%; | ||||
|   color: navy; | ||||
|   background-color: #eee; | ||||
|   float:right; | ||||
|   vertical-align: bottom; | ||||
| } | ||||
| #pt-footer img { | ||||
|   vertical-align: bottom; | ||||
| @ -300,7 +317,7 @@ article.pt-overview section header { | ||||
|   text-align: center; | ||||
|   border-top-left-radius: 1rem; | ||||
|   border-top-right-radius: 1rem; | ||||
|   background-image: linear-gradient(to bottom, #444, #888); | ||||
|   background-image: linear-gradient(to bottom, var(--dark), var(--lighter-dark)); | ||||
|   padding: .5rem 1rem; | ||||
|   color: white; | ||||
| } | ||||
| @ -308,7 +325,7 @@ article.pt-overview section div { | ||||
|   padding: .5rem; | ||||
| } | ||||
| article.pt-overview section div hr { | ||||
|   color: #444; | ||||
|   color: var(--dark); | ||||
|   margin: .5rem -.5rem; | ||||
| } | ||||
| article.pt-overview section div p { | ||||
|  | ||||
							
								
								
									
										106
									
								
								src/names-to-lower.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/names-to-lower.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | ||||
| -- Church | ||||
| ALTER TABLE pt."Church" RENAME COLUMN "ChurchId" TO id; | ||||
| ALTER TABLE pt."Church" RENAME COLUMN "Name" TO church_name; | ||||
| ALTER TABLE pt."Church" RENAME COLUMN "City" TO city; | ||||
| ALTER TABLE pt."Church" RENAME COLUMN "ST" TO state; | ||||
| ALTER TABLE pt."Church" RENAME COLUMN "HasVirtualPrayerRoomInterface" TO has_vps_interface; | ||||
| ALTER TABLE pt."Church" RENAME COLUMN "InterfaceAddress" TO interface_address; | ||||
| ALTER TABLE pt."Church" RENAME CONSTRAINT "PK_Church" TO pk_church; | ||||
| ALTER TABLE pt."Church" RENAME TO church; | ||||
| 
 | ||||
| -- List Preference | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "SmallGroupId" TO small_group_id; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "DaysToExpire" TO days_to_expire; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "DaysToKeepNew" TO days_to_keep_new; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "LongTermUpdateWeeks" TO long_term_update_weeks; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "EmailFromName" TO email_from_name; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "EmailFromAddress" TO email_from_address; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "ListFonts" TO fonts; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "HeadingColor" TO heading_color; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "LineColor" TO line_color; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "HeadingFontSize" TO heading_font_size; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "TextFontSize" TO text_font_size; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "RequestSort" TO request_sort; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "GroupPassword" TO group_password; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "DefaultEmailType" TO default_email_type; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "IsPublic" TO is_public; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "TimeZoneId" TO time_zone_id; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "PageSize" TO page_size; | ||||
| ALTER TABLE pt."ListPreference" RENAME COLUMN "AsOfDateDisplay" TO as_of_date_display; | ||||
| ALTER TABLE pt."ListPreference" RENAME CONSTRAINT "PK_ListPreference" TO pk_list_preference; | ||||
| ALTER TABLE pt."ListPreference" RENAME CONSTRAINT "FK_ListPreference_SmallGroup_SmallGroupId" TO fk_list_preference_small_group_id; | ||||
| ALTER TABLE pt."ListPreference" RENAME CONSTRAINT "FK_ListPreference_TimeZone_TimeZoneId" TO fk_list_preference_time_zone_id; | ||||
| ALTER TABLE pt."ListPreference" RENAME TO list_preference; | ||||
| 
 | ||||
| ALTER INDEX pt."IX_ListPreference_TimeZoneId" RENAME TO ix_list_preference_time_zone_id; | ||||
| 
 | ||||
| -- Small Group Member | ||||
| ALTER TABLE pt."Member" RENAME COLUMN "MemberId" TO id; | ||||
| ALTER TABLE pt."Member" RENAME COLUMN "SmallGroupId" TO small_group_id; | ||||
| ALTER TABLE pt."Member" RENAME COLUMN "MemberName" TO member_name; | ||||
| ALTER TABLE pt."Member" RENAME COLUMN "Email" TO email; | ||||
| ALTER TABLE pt."Member" RENAME COLUMN "Format" TO email_format; | ||||
| ALTER TABLE pt."Member" RENAME CONSTRAINT "PK_Member" TO pk_member; | ||||
| ALTER TABLE pt."Member" RENAME CONSTRAINT "FK_Member_SmallGroup_SmallGroupId" TO fk_member_small_group_id; | ||||
| ALTER TABLE pt."Member" RENAME TO member; | ||||
| 
 | ||||
| ALTER INDEX pt."IX_Member_SmallGroupId" RENAME TO ix_member_small_group_id; | ||||
| 
 | ||||
| -- Prayer Request | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "PrayerRequestId" TO id; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "RequestType" TO request_type; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "UserId" TO user_id; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "SmallGroupId" TO small_group_id; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "EnteredDate" TO entered_date; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "UpdatedDate" TO updated_date; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "Requestor" TO requestor; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "Text" TO request_text; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "NotifyChaplain" TO notify_chaplain; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME COLUMN "Expiration" TO expiration; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME CONSTRAINT "PK_PrayerRequest" TO pk_prayer_request; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME CONSTRAINT "FK_PrayerRequest_User_UserId" TO fk_prayer_request_user_id; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME CONSTRAINT "FK_PrayerRequest_SmallGroup_SmallGroupId" TO fk_prayer_request_small_group_id; | ||||
| ALTER TABLE pt."PrayerRequest" RENAME TO prayer_request; | ||||
| 
 | ||||
| ALTER INDEX pt."IX_PrayerRequest_UserId" RENAME TO ix_prayer_request_user_id; | ||||
| ALTER INDEX pt."IX_PrayerRequest_SmallGroupId" RENAME TO ix_prayer_request_small_group_id; | ||||
| ALTER INDEX pt."IX_PrayerRequest_Requestor_TRGM" RENAME TO ix_prayer_request_trgm_requestor; | ||||
| ALTER INDEX pt."IX_PrayerRequest_Text_TRGM" RENAME TO ix_prayer_request_trgm_request_text; | ||||
| -- Small Group | ||||
| ALTER TABLE pt."SmallGroup" RENAME COLUMN "SmallGroupId" TO id; | ||||
| ALTER TABLE pt."SmallGroup" RENAME COLUMN "ChurchId" TO church_id; | ||||
| ALTER TABLE pt."SmallGroup" RENAME COLUMN "Name" TO group_name; | ||||
| ALTER TABLE pt."SmallGroup" RENAME CONSTRAINT "PK_SmallGroup" TO pk_small_group; | ||||
| ALTER TABLE pt."SmallGroup" RENAME CONSTRAINT "FK_SmallGroup_Church_ChurchId" TO fk_small_group_church_id; | ||||
| ALTER TABLE pt."SmallGroup" RENAME TO small_group; | ||||
| 
 | ||||
| ALTER INDEX pt."IX_SmallGroup_ChurchId" RENAME TO ix_small_group_church_id; | ||||
| 
 | ||||
| -- Time Zone | ||||
| ALTER TABLE pt."TimeZone" RENAME COLUMN "TimeZoneId" TO id; | ||||
| ALTER TABLE pt."TimeZone" RENAME COLUMN "Description" TO description; | ||||
| ALTER TABLE pt."TimeZone" RENAME COLUMN "SortOrder" TO sort_order; | ||||
| ALTER TABLE pt."TimeZone" RENAME COLUMN "IsActive" TO is_active; | ||||
| ALTER TABLE pt."TimeZone" RENAME CONSTRAINT "PK_TimeZone" TO pk_time_zone; | ||||
| ALTER TABLE pt."TimeZone" RENAME TO time_zone; | ||||
| 
 | ||||
| -- User | ||||
| ALTER TABLE pt."User" RENAME COLUMN "UserId" TO id; | ||||
| ALTER TABLE pt."User" RENAME COLUMN "FirstName" TO first_name; | ||||
| ALTER TABLE pt."User" RENAME COLUMN "LastName" TO last_name; | ||||
| ALTER TABLE pt."User" RENAME COLUMN "EmailAddress" TO email; | ||||
| ALTER TABLE pt."User" RENAME COLUMN "IsSystemAdmin" TO is_admin; | ||||
| ALTER TABLE pt."User" RENAME COLUMN "PasswordHash" TO password_hash; | ||||
| ALTER TABLE pt."User" RENAME COLUMN "Salt" TO salt; | ||||
| ALTER TABLE pt."User" RENAME CONSTRAINT "PK_User" TO pk_pt_user; | ||||
| ALTER TABLE pt."User" RENAME TO pt_user; | ||||
| 
 | ||||
| -- User / Small Group | ||||
| ALTER TABLE pt."User_SmallGroup" RENAME COLUMN "UserId" TO user_id; | ||||
| ALTER TABLE pt."User_SmallGroup" RENAME COLUMN "SmallGroupId" TO small_group_id; | ||||
| ALTER TABLE pt."User_SmallGroup" RENAME CONSTRAINT "PK_User_SmallGroup" TO pk_user_small_group; | ||||
| ALTER TABLE pt."User_SmallGroup" RENAME CONSTRAINT "FK_User_SmallGroup_User_UserId" TO fk_user_small_group_user_id; | ||||
| ALTER TABLE pt."User_SmallGroup" RENAME CONSTRAINT "FK_User_SmallGroup_SmallGroup_SmallGroupId" TO fk_user_small_group_small_group_id; | ||||
| ALTER TABLE pt."User_SmallGroup" RENAME TO user_small_group; | ||||
| 
 | ||||
| ALTER INDEX pt."IX_User_SmallGroup_SmallGroupId" RENAME TO ix_user_small_group_small_group_id; | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user