Version 8 #43

Merged
danieljsummers merged 37 commits from version-8 into main 2022-08-19 19:08:31 +00:00
19 changed files with 1167 additions and 1241 deletions
Showing only changes of commit f6c483b7c0 - Show all commits

View File

@ -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)

View File

@ -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

View File

@ -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 ())

View File

@ -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

View File

@ -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

View File

@ -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"
}
]

View File

@ -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"
}
]

View File

@ -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 []
]

View File

@ -159,7 +159,7 @@ module Navigation =
span [ _class "u" ] [ locStr s["Currently Logged On"] ]
rawText "&nbsp; &nbsp;"
icon "person"
strong [] [ str u.fullName ]
strong [] [ str u.Name ]
rawText "&nbsp; &nbsp; "
| 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 " &nbsp;"
]
| 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 " &bull; "
rawText " &nbsp; "
a [ _href "/legal/terms-of-service" ] [ locStr s["Terms of Service"] ]
rawText " &bull; "
rawText " &nbsp; "
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

View File

@ -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 " &nbsp; &nbsp; &nbsp; "
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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp;"; locStr s["Maintain Prayer Requests"]
]
spacer
a [ _class "pt-icon-link"; _href "/prayer-requests"; _title s["Maintain Prayer Requests"].Value ] [
icon "compare_arrows"; rawText " &nbsp;"; 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

View File

@ -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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp; "
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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp; "
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 " &nbsp;"; 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 " &nbsp;"; 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 "&nbsp; &nbsp; "; 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 "&nbsp; &nbsp; "; 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 " &nbsp;"; locStr s["Colors"] ]; rawText " ***" ]
div [ _fieldRow ] [
fieldset [] [
legend [] [ strong [] [ icon "font_download"; rawText " &nbsp;"; 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 " &nbsp;"; 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 "&nbsp; &nbsp; "; 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 "&nbsp; &nbsp; "; 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 " &nbsp;"
radio name $"{name}_Private" (string GroupVisibility.PrivateList) value
label [ _for $"{name}_Private" ] [ locStr s["Private"] ]
rawText " &nbsp;"
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 " &nbsp;"; 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 " &nbsp;"; 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 " &nbsp;"
radio name $"{name}_Private" (string RequestVisibility.``private``) value
label [ _for $"{name}_Private" ] [ locStr s["Private"] ]
rawText " &nbsp;"
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."]

View File

@ -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"]
]

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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;