Towards using short GUIDs (#1)
Also updated dependencies and moved to .NET Core 2.2; the Giraffe token router doesn't have a parser for short GUIDs yet
This commit is contained in:
parent
fae4ebf9e7
commit
dab6c59a37
@ -3,15 +3,11 @@ module PrayerTracker.DataAccess
|
|||||||
|
|
||||||
open FSharp.Control.Tasks.ContextInsensitive
|
open FSharp.Control.Tasks.ContextInsensitive
|
||||||
open Microsoft.EntityFrameworkCore
|
open Microsoft.EntityFrameworkCore
|
||||||
|
open Microsoft.FSharpLu
|
||||||
open PrayerTracker.Entities
|
open PrayerTracker.Entities
|
||||||
open System.Collections.Generic
|
open System.Collections.Generic
|
||||||
open System.Linq
|
open System.Linq
|
||||||
|
|
||||||
/// EF can return null for record types with the CLIMutable attribute; this converts a possibly-null record type to an
|
|
||||||
/// option
|
|
||||||
let optRec<'T> (r : 'T) =
|
|
||||||
match box r with null -> None | _ -> Some r
|
|
||||||
|
|
||||||
type AppDbContext with
|
type AppDbContext with
|
||||||
|
|
||||||
(*-- DISCONNECTED DATA EXTENSIONS --*)
|
(*-- DISCONNECTED DATA EXTENSIONS --*)
|
||||||
@ -34,7 +30,7 @@ type AppDbContext with
|
|||||||
member this.TryChurchById cId =
|
member this.TryChurchById cId =
|
||||||
task {
|
task {
|
||||||
let! church = this.Churches.AsNoTracking().FirstOrDefaultAsync (fun c -> c.churchId = cId)
|
let! church = this.Churches.AsNoTracking().FirstOrDefaultAsync (fun c -> c.churchId = cId)
|
||||||
return optRec church
|
return Option.fromObject church
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find all churches
|
/// Find all churches
|
||||||
@ -50,7 +46,7 @@ type AppDbContext with
|
|||||||
member this.TryMemberById mId =
|
member this.TryMemberById mId =
|
||||||
task {
|
task {
|
||||||
let! mbr = this.Members.AsNoTracking().FirstOrDefaultAsync (fun m -> m.memberId = mId)
|
let! mbr = this.Members.AsNoTracking().FirstOrDefaultAsync (fun m -> m.memberId = mId)
|
||||||
return optRec mbr
|
return Option.fromObject mbr
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find all members for a small group
|
/// Find all members for a small group
|
||||||
@ -74,7 +70,7 @@ type AppDbContext with
|
|||||||
member this.TryRequestById reqId =
|
member this.TryRequestById reqId =
|
||||||
task {
|
task {
|
||||||
let! req = this.PrayerRequests.AsNoTracking().FirstOrDefaultAsync (fun pr -> pr.prayerRequestId = reqId)
|
let! req = this.PrayerRequests.AsNoTracking().FirstOrDefaultAsync (fun pr -> pr.prayerRequestId = reqId)
|
||||||
return optRec req
|
return Option.fromObject req
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all (or active) requests for a small group as of now or the specified date
|
/// Get all (or active) requests for a small group as of now or the specified date
|
||||||
@ -121,7 +117,7 @@ type AppDbContext with
|
|||||||
this.SmallGroups.AsNoTracking()
|
this.SmallGroups.AsNoTracking()
|
||||||
.Include(fun sg -> sg.preferences)
|
.Include(fun sg -> sg.preferences)
|
||||||
.FirstOrDefaultAsync (fun sg -> sg.smallGroupId = gId)
|
.FirstOrDefaultAsync (fun sg -> sg.smallGroupId = gId)
|
||||||
return optRec grp
|
return Option.fromObject grp
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get small groups that are public or password protected
|
/// Get small groups that are public or password protected
|
||||||
@ -176,7 +172,7 @@ type AppDbContext with
|
|||||||
.ToListAsync ()
|
.ToListAsync ()
|
||||||
return grps
|
return grps
|
||||||
|> Seq.map (fun grp -> grp.smallGroupId.ToString "N", sprintf "%s | %s" grp.church.name grp.name)
|
|> Seq.map (fun grp -> grp.smallGroupId.ToString "N", sprintf "%s | %s" grp.church.name grp.name)
|
||||||
|> Map.ofSeq
|
|> List.ofSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Log on a small group
|
/// Log on a small group
|
||||||
@ -213,7 +209,7 @@ type AppDbContext with
|
|||||||
member this.TryTimeZoneById tzId =
|
member this.TryTimeZoneById tzId =
|
||||||
task {
|
task {
|
||||||
let! tz = this.TimeZones.FirstOrDefaultAsync (fun t -> t.timeZoneId = tzId)
|
let! tz = this.TimeZones.FirstOrDefaultAsync (fun t -> t.timeZoneId = tzId)
|
||||||
return optRec tz
|
return Option.fromObject tz
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all time zones
|
/// Get all time zones
|
||||||
@ -229,7 +225,7 @@ type AppDbContext with
|
|||||||
member this.TryUserById uId =
|
member this.TryUserById uId =
|
||||||
task {
|
task {
|
||||||
let! user = this.Users.AsNoTracking().FirstOrDefaultAsync (fun u -> u.userId = uId)
|
let! user = this.Users.AsNoTracking().FirstOrDefaultAsync (fun u -> u.userId = uId)
|
||||||
return optRec user
|
return Option.fromObject user
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a user by its e-mail address and authorized small group
|
/// Find a user by its e-mail address and authorized small group
|
||||||
@ -239,14 +235,14 @@ type AppDbContext with
|
|||||||
this.Users.AsNoTracking().FirstOrDefaultAsync (fun u ->
|
this.Users.AsNoTracking().FirstOrDefaultAsync (fun u ->
|
||||||
u.emailAddress = email
|
u.emailAddress = email
|
||||||
&& u.smallGroups.Any (fun xref -> xref.smallGroupId = gId))
|
&& u.smallGroups.Any (fun xref -> xref.smallGroupId = gId))
|
||||||
return optRec user
|
return Option.fromObject user
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a user by its Id (tracked entity), eagerly loading the user's groups
|
/// Find a user by its Id (tracked entity), eagerly loading the user's groups
|
||||||
member this.TryUserByIdWithGroups uId =
|
member this.TryUserByIdWithGroups uId =
|
||||||
task {
|
task {
|
||||||
let! user = this.Users.Include(fun u -> u.smallGroups).FirstOrDefaultAsync (fun u -> u.userId = uId)
|
let! user = this.Users.Include(fun u -> u.smallGroups).FirstOrDefaultAsync (fun u -> u.userId = uId)
|
||||||
return optRec user
|
return Option.fromObject user
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a list of all users
|
/// Get a list of all users
|
||||||
@ -274,7 +270,7 @@ type AppDbContext with
|
|||||||
u.emailAddress = email
|
u.emailAddress = email
|
||||||
&& u.passwordHash = pwHash
|
&& u.passwordHash = pwHash
|
||||||
&& u.smallGroups.Any (fun xref -> xref.smallGroupId = gId))
|
&& u.smallGroups.Any (fun xref -> xref.smallGroupId = gId))
|
||||||
return optRec user
|
return Option.fromObject user
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a user based on credentials stored in a cookie
|
/// Find a user based on credentials stored in a cookie
|
||||||
|
@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FSharp.EFCore.OptionConverter" Version="1.0.0" />
|
<PackageReference Include="FSharp.EFCore.OptionConverter" Version="1.0.0" />
|
||||||
<PackageReference Include="NodaTime" Version="2.4.0" />
|
<PackageReference Include="Microsoft.FSharpLu" Version="0.10.29" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" />
|
<PackageReference Include="NodaTime" Version="2.4.4" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
|
||||||
<PackageReference Include="TaskBuilder.fs" Version="2.1.0" />
|
<PackageReference Include="TaskBuilder.fs" Version="2.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="FSharp.Core" Version="4.5.2" />
|
<PackageReference Update="FSharp.Core" Version="4.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -15,9 +15,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Expecto" Version="8.4.2" />
|
<PackageReference Include="Expecto" Version="8.8.0" />
|
||||||
<PackageReference Include="Expecto.VisualStudio.TestAdapter" Version="10.0.0" />
|
<PackageReference Include="Expecto.VisualStudio.TestAdapter" Version="10.0.2" />
|
||||||
<PackageReference Include="NodaTime.Testing" Version="2.4.0" />
|
<PackageReference Include="NodaTime.Testing" Version="2.4.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="FSharp.Core" Version="4.5.2" />
|
<PackageReference Update="FSharp.Core" Version="4.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
open Giraffe.GiraffeViewEngine
|
open Giraffe.GiraffeViewEngine
|
||||||
open PrayerTracker.Entities
|
open PrayerTracker.Entities
|
||||||
open PrayerTracker.ViewModels
|
open PrayerTracker.ViewModels
|
||||||
open System
|
|
||||||
open System.Collections.Generic
|
|
||||||
|
|
||||||
/// View for the church edit page
|
/// View for the church edit page
|
||||||
let edit (m : EditChurch) ctx vi =
|
let edit (m : EditChurch) ctx vi =
|
||||||
@ -14,7 +12,7 @@ let edit (m : EditChurch) ctx vi =
|
|||||||
style [ _scoped ]
|
style [ _scoped ]
|
||||||
[ rawText "#name { width: 20rem; } #city { width: 10rem; } #st { width: 3rem; } #interfaceAddress { width: 30rem; }" ]
|
[ rawText "#name { width: 20rem; } #city { width: 10rem; } #st { width: 3rem; } #interfaceAddress { width: 30rem; }" ]
|
||||||
csrfToken ctx
|
csrfToken ctx
|
||||||
input [ _type "hidden"; _name "churchId"; _value (m.churchId.ToString "N") ]
|
input [ _type "hidden"; _name "churchId"; _value (flatGuid m.churchId) ]
|
||||||
div [ _class "pt-field-row" ] [
|
div [ _class "pt-field-row" ] [
|
||||||
div [ _class "pt-field" ] [
|
div [ _class "pt-field" ] [
|
||||||
label [ _for "name" ] [ encLocText s.["Church Name"] ]
|
label [ _for "name" ] [ encLocText s.["Church Name"] ]
|
||||||
@ -79,7 +77,7 @@ let maintain (churches : Church list) (stats : Map<string, ChurchStats>) ctx vi
|
|||||||
]
|
]
|
||||||
churches
|
churches
|
||||||
|> List.map (fun ch ->
|
|> List.map (fun ch ->
|
||||||
let chId = ch.churchId.ToString "N"
|
let chId = flatGuid ch.churchId
|
||||||
let delAction = sprintf "/church/%s/delete" chId
|
let delAction = sprintf "/church/%s/delete" chId
|
||||||
let delPrompt = s.["Are you want to delete this {0}? This action cannot be undone.",
|
let delPrompt = s.["Are you want to delete this {0}? This action cannot be undone.",
|
||||||
sprintf "%s (%s)" (s.["Church"].Value.ToLower ()) ch.name]
|
sprintf "%s (%s)" (s.["Church"].Value.ToLower ()) ch.name]
|
||||||
|
@ -7,6 +7,7 @@ open Microsoft.AspNetCore.Antiforgery
|
|||||||
open Microsoft.AspNetCore.Http
|
open Microsoft.AspNetCore.Http
|
||||||
open Microsoft.AspNetCore.Mvc.Localization
|
open Microsoft.AspNetCore.Mvc.Localization
|
||||||
open Microsoft.Extensions.Localization
|
open Microsoft.Extensions.Localization
|
||||||
|
open System
|
||||||
open System.IO
|
open System.IO
|
||||||
open System.Text.Encodings.Web
|
open System.Text.Encodings.Web
|
||||||
|
|
||||||
@ -101,8 +102,11 @@ let selectDefault text = sprintf "— %s —" text
|
|||||||
/// Generate a standard submit button with icon and text
|
/// Generate a standard submit button with icon and text
|
||||||
let submit attrs ico text = button (_type "submit" :: attrs) [ icon ico; rawText " "; encLocText text ]
|
let submit attrs ico text = button (_type "submit" :: attrs) [ icon ico; rawText " "; encLocText text ]
|
||||||
|
|
||||||
|
/// Format a GUID with no dashes (used for URLs and forms)
|
||||||
|
let flatGuid (x : Guid) = x.ToString "N"
|
||||||
|
|
||||||
/// An empty GUID string (used for "add" actions)
|
/// An empty GUID string (used for "add" actions)
|
||||||
let emptyGuid = System.Guid.Empty.ToString "N"
|
let emptyGuid = flatGuid Guid.Empty
|
||||||
|
|
||||||
|
|
||||||
/// blockquote tag
|
/// blockquote tag
|
||||||
|
@ -17,7 +17,7 @@ let edit (m : EditRequest) today ctx vi =
|
|||||||
let pageTitle = match m.isNew () with true -> "Add a New Request" | false -> "Edit Request"
|
let pageTitle = match m.isNew () with true -> "Add a New Request" | false -> "Edit Request"
|
||||||
[ form [ _action "/prayer-request/save"; _method "post"; _class "pt-center-columns" ] [
|
[ form [ _action "/prayer-request/save"; _method "post"; _class "pt-center-columns" ] [
|
||||||
csrfToken ctx
|
csrfToken ctx
|
||||||
input [ _type "hidden"; _name "requestId"; _value (m.requestId.ToString "N") ]
|
input [ _type "hidden"; _name "requestId"; _value (flatGuid m.requestId) ]
|
||||||
div [ _class "pt-field-row" ] [
|
div [ _class "pt-field-row" ] [
|
||||||
yield div [ _class "pt-field" ] [
|
yield div [ _class "pt-field" ] [
|
||||||
label [ _for "requestType" ] [ encLocText s.["Request Type"] ]
|
label [ _for "requestType" ] [ encLocText s.["Request Type"] ]
|
||||||
@ -139,7 +139,7 @@ let lists (grps : SmallGroup list) vi =
|
|||||||
]
|
]
|
||||||
grps
|
grps
|
||||||
|> List.map (fun grp ->
|
|> List.map (fun grp ->
|
||||||
let grpId = grp.smallGroupId.ToString "N"
|
let grpId = flatGuid grp.smallGroupId
|
||||||
tr [] [
|
tr [] [
|
||||||
match grp.preferences.isPublic with
|
match grp.preferences.isPublic with
|
||||||
| true ->
|
| true ->
|
||||||
@ -175,7 +175,7 @@ let maintain (reqs : PrayerRequest seq) (grp : SmallGroup) onlyActive (ctx : Htt
|
|||||||
let requests =
|
let requests =
|
||||||
reqs
|
reqs
|
||||||
|> Seq.map (fun req ->
|
|> Seq.map (fun req ->
|
||||||
let reqId = req.prayerRequestId.ToString "N"
|
let reqId = flatGuid req.prayerRequestId
|
||||||
let reqText = Utils.htmlToPlainText req.text
|
let reqText = Utils.htmlToPlainText req.text
|
||||||
let delAction = sprintf "/prayer-request/%s/delete" reqId
|
let delAction = sprintf "/prayer-request/%s/delete" reqId
|
||||||
let delPrompt = s.["Are you want to delete this prayer request? This action cannot be undone.\\n(If the prayer request has been answered, or an event has passed, consider inactivating it instead.)"].Value
|
let delPrompt = s.["Are you want to delete this prayer request? This action cannot be undone.\\n(If the prayer request has been answered, or an event has passed, consider inactivating it instead.)"].Value
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Giraffe" Version="3.1.0" />
|
<PackageReference Include="Giraffe" Version="3.6.0" />
|
||||||
<PackageReference Include="MailKit" Version="2.0.6" />
|
<PackageReference Include="MailKit" Version="2.1.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="2.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -89,7 +89,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="FSharp.Core" Version="4.5.2" />
|
<PackageReference Update="FSharp.Core" Version="4.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -20,7 +20,7 @@ let announcement isAdmin ctx vi =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
match isAdmin with
|
match isAdmin with
|
||||||
| true ->
|
| true ->
|
||||||
yield div [ _class "pt-field-row" ] [
|
yield div [ _class "pt-field-row" ] [
|
||||||
div [ _class "pt-field" ] [
|
div [ _class "pt-field" ] [
|
||||||
label [] [ encLocText s.["Send Announcement to"]; rawText ":" ]
|
label [] [ encLocText s.["Send Announcement to"]; rawText ":" ]
|
||||||
@ -77,7 +77,7 @@ let edit (m : EditSmallGroup) (churches : Church list) ctx vi =
|
|||||||
let pageTitle = match m.isNew () with true -> "Add a New Group" | false -> "Edit Group"
|
let pageTitle = match m.isNew () with true -> "Add a New Group" | false -> "Edit Group"
|
||||||
form [ _action "/small-group/save"; _method "post"; _class "pt-center-columns" ] [
|
form [ _action "/small-group/save"; _method "post"; _class "pt-center-columns" ] [
|
||||||
csrfToken ctx
|
csrfToken ctx
|
||||||
input [ _type "hidden"; _name "smallGroupId"; _value (m.smallGroupId.ToString "N") ]
|
input [ _type "hidden"; _name "smallGroupId"; _value (flatGuid m.smallGroupId) ]
|
||||||
div [ _class "pt-field-row" ] [
|
div [ _class "pt-field-row" ] [
|
||||||
div [ _class "pt-field" ] [
|
div [ _class "pt-field" ] [
|
||||||
label [ _for "name" ] [ encLocText s.["Group Name"] ]
|
label [ _for "name" ] [ encLocText s.["Group Name"] ]
|
||||||
@ -89,9 +89,9 @@ let edit (m : EditSmallGroup) (churches : Church list) ctx vi =
|
|||||||
label [ _for "churchId" ] [ encLocText s.["Church"] ]
|
label [ _for "churchId" ] [ encLocText s.["Church"] ]
|
||||||
seq {
|
seq {
|
||||||
yield "", selectDefault s.["Select Church"].Value
|
yield "", selectDefault s.["Select Church"].Value
|
||||||
yield! churches |> List.map (fun c -> c.churchId.ToString "N", c.name)
|
yield! churches |> List.map (fun c -> flatGuid c.churchId, c.name)
|
||||||
}
|
}
|
||||||
|> selectList "churchId" (m.churchId.ToString "N") [ _required ]
|
|> selectList "churchId" (flatGuid m.churchId) [ _required ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
div [ _class "pt-field-row" ] [ submit [] "save" s.["Save Group"] ]
|
div [ _class "pt-field-row" ] [ submit [] "save" s.["Save Group"] ]
|
||||||
@ -108,7 +108,7 @@ let editMember (m : EditMember) (typs : (string * LocalizedString) seq) ctx vi =
|
|||||||
form [ _action "/small-group/member/save"; _method "post"; _class "pt-center-columns" ] [
|
form [ _action "/small-group/member/save"; _method "post"; _class "pt-center-columns" ] [
|
||||||
style [ _scoped ] [ rawText "#memberName { width: 15rem; } #emailAddress { width: 20rem; }" ]
|
style [ _scoped ] [ rawText "#memberName { width: 15rem; } #emailAddress { width: 20rem; }" ]
|
||||||
csrfToken ctx
|
csrfToken ctx
|
||||||
input [ _type "hidden"; _name "memberId"; _value (m.memberId.ToString "N") ]
|
input [ _type "hidden"; _name "memberId"; _value (flatGuid m.memberId) ]
|
||||||
div [ _class "pt-field-row" ] [
|
div [ _class "pt-field-row" ] [
|
||||||
div [ _class "pt-field" ] [
|
div [ _class "pt-field" ] [
|
||||||
label [ _for "memberName" ] [ encLocText s.["Member Name"] ]
|
label [ _for "memberName" ] [ encLocText s.["Member Name"] ]
|
||||||
@ -148,7 +148,7 @@ let logOn (grps : SmallGroup list) grpId ctx vi =
|
|||||||
| _ ->
|
| _ ->
|
||||||
yield "", selectDefault s.["Select Group"].Value
|
yield "", selectDefault s.["Select Group"].Value
|
||||||
yield! grps
|
yield! grps
|
||||||
|> List.map (fun grp -> grp.smallGroupId.ToString "N", sprintf "%s | %s" grp.church.name grp.name)
|
|> List.map (fun grp -> flatGuid grp.smallGroupId, sprintf "%s | %s" grp.church.name grp.name)
|
||||||
}
|
}
|
||||||
|> selectList "smallGroupId" grpId [ _required ]
|
|> selectList "smallGroupId" grpId [ _required ]
|
||||||
]
|
]
|
||||||
@ -197,7 +197,7 @@ let maintain (grps : SmallGroup list) ctx vi =
|
|||||||
]
|
]
|
||||||
grps
|
grps
|
||||||
|> List.map (fun g ->
|
|> List.map (fun g ->
|
||||||
let grpId = g.smallGroupId.ToString "N"
|
let grpId = flatGuid g.smallGroupId
|
||||||
let delAction = sprintf "/small-group/%s/delete" grpId
|
let delAction = sprintf "/small-group/%s/delete" grpId
|
||||||
let delPrompt = s.["Are you want to delete this {0}? This action cannot be undone.",
|
let delPrompt = s.["Are you want to delete this {0}? This action cannot be undone.",
|
||||||
sprintf "%s (%s)" (s.["Small Group"].Value.ToLower ()) g.name].Value
|
sprintf "%s (%s)" (s.["Small Group"].Value.ToLower ()) g.name].Value
|
||||||
@ -243,7 +243,7 @@ let members (mbrs : Member list) (emailTyps : Map<string, LocalizedString>) ctx
|
|||||||
]
|
]
|
||||||
mbrs
|
mbrs
|
||||||
|> List.map (fun mbr ->
|
|> List.map (fun mbr ->
|
||||||
let mbrId = mbr.memberId.ToString "N"
|
let mbrId = flatGuid mbr.memberId
|
||||||
let delAction = sprintf "/small-group/member/%s/delete" mbrId
|
let delAction = sprintf "/small-group/member/%s/delete" mbrId
|
||||||
let delPrompt = s.["Are you want to delete this {0} ({1})? This action cannot be undone.",
|
let delPrompt = s.["Are you want to delete this {0} ({1})? This action cannot be undone.",
|
||||||
s.["group member"], mbr.memberName].Value
|
s.["group member"], mbr.memberName].Value
|
||||||
|
@ -5,12 +5,12 @@ open PrayerTracker.Entities
|
|||||||
open PrayerTracker.ViewModels
|
open PrayerTracker.ViewModels
|
||||||
|
|
||||||
/// View for the group assignment page
|
/// View for the group assignment page
|
||||||
let assignGroups m (groups : Map<string, string>) (curGroups : string list) ctx vi =
|
let assignGroups m groups curGroups ctx vi =
|
||||||
let s = I18N.localizer.Force ()
|
let s = I18N.localizer.Force ()
|
||||||
let pageTitle = sprintf "%s • %A" m.userName s.["Assign Groups"]
|
let pageTitle = sprintf "%s • %A" m.userName s.["Assign Groups"]
|
||||||
form [ _action "/user/small-groups/save"; _method "post"; _class "pt-center-columns" ] [
|
form [ _action "/user/small-groups/save"; _method "post"; _class "pt-center-columns" ] [
|
||||||
csrfToken ctx
|
csrfToken ctx
|
||||||
input [ _type "hidden"; _name "userId"; _value (m.userId.ToString "N") ]
|
input [ _type "hidden"; _name "userId"; _value (flatGuid m.userId) ]
|
||||||
input [ _type "hidden"; _name "userName"; _value m.userName ]
|
input [ _type "hidden"; _name "userName"; _value m.userName ]
|
||||||
table [ _class "pt-table" ] [
|
table [ _class "pt-table" ] [
|
||||||
thead [] [
|
thead [] [
|
||||||
@ -20,19 +20,18 @@ let assignGroups m (groups : Map<string, string>) (curGroups : string list) ctx
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
groups
|
groups
|
||||||
|> Seq.map (fun grp ->
|
|> List.map (fun (grpId, grpName) ->
|
||||||
let inputId = sprintf "id-%s" grp.Key
|
let inputId = sprintf "id-%s" grpId
|
||||||
tr [] [
|
tr [] [
|
||||||
td [] [
|
td [] [
|
||||||
input [ yield _type "checkbox"
|
input [ yield _type "checkbox"
|
||||||
yield _name "smallGroups"
|
yield _name "smallGroups"
|
||||||
yield _id inputId
|
yield _id inputId
|
||||||
yield _value grp.Key
|
yield _value grpId
|
||||||
match curGroups |> List.contains grp.Key with true -> yield _checked | false -> () ]
|
match curGroups |> List.contains grpId with true -> yield _checked | false -> () ]
|
||||||
]
|
]
|
||||||
td [] [ label [ _for inputId ] [ encodedText grp.Value ] ]
|
td [] [ label [ _for inputId ] [ encodedText grpName ] ]
|
||||||
])
|
])
|
||||||
|> List.ofSeq
|
|
||||||
|> tbody []
|
|> tbody []
|
||||||
]
|
]
|
||||||
div [ _class "pt-field-row" ] [ submit [] "save" s.["Save Group Assignments"] ]
|
div [ _class "pt-field-row" ] [ submit [] "save" s.["Save Group Assignments"] ]
|
||||||
@ -89,7 +88,7 @@ let edit (m : EditUser) ctx vi =
|
|||||||
style [ _scoped ]
|
style [ _scoped ]
|
||||||
[ rawText "#firstName, #lastName, #password, #passwordConfirm { width: 10rem; } #emailAddress { width: 20rem; } " ]
|
[ rawText "#firstName, #lastName, #password, #passwordConfirm { width: 10rem; } #emailAddress { width: 20rem; } " ]
|
||||||
csrfToken ctx
|
csrfToken ctx
|
||||||
input [ _type "hidden"; _name "userId"; _value (m.userId.ToString "N") ]
|
input [ _type "hidden"; _name "userId"; _value (flatGuid m.userId) ]
|
||||||
div [ _class "pt-field-row" ] [
|
div [ _class "pt-field-row" ] [
|
||||||
div [ _class "pt-field" ] [
|
div [ _class "pt-field" ] [
|
||||||
label [ _for "firstName" ] [ encLocText s.["First Name"] ]
|
label [ _for "firstName" ] [ encLocText s.["First Name"] ]
|
||||||
@ -131,7 +130,7 @@ let edit (m : EditUser) ctx vi =
|
|||||||
|
|
||||||
|
|
||||||
/// View for the user log on page
|
/// View for the user log on page
|
||||||
let logOn (m : UserLogOn) (groups : Map<string, string>) ctx vi =
|
let logOn (m : UserLogOn) groups ctx vi =
|
||||||
let s = I18N.localizer.Force ()
|
let s = I18N.localizer.Force ()
|
||||||
form [ _action "/user/log-on"; _method "post"; _class "pt-center-columns" ] [
|
form [ _action "/user/log-on"; _method "post"; _class "pt-center-columns" ] [
|
||||||
style [ _scoped ] [ rawText "#emailAddress { width: 20rem; }" ]
|
style [ _scoped ] [ rawText "#emailAddress { width: 20rem; }" ]
|
||||||
@ -153,7 +152,7 @@ let logOn (m : UserLogOn) (groups : Map<string, string>) ctx vi =
|
|||||||
label [ _for "smallGroupId" ] [ encLocText s.["Group"] ]
|
label [ _for "smallGroupId" ] [ encLocText s.["Group"] ]
|
||||||
seq {
|
seq {
|
||||||
yield "", selectDefault s.["Select Group"].Value
|
yield "", selectDefault s.["Select Group"].Value
|
||||||
yield! groups |> Seq.sortBy (fun x -> x.Value) |> Seq.map (fun x -> x.Key, x.Value)
|
yield! groups
|
||||||
}
|
}
|
||||||
|> selectList "smallGroupId" "" [ _required ]
|
|> selectList "smallGroupId" "" [ _required ]
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ let maintain (users : User list) ctx vi =
|
|||||||
]
|
]
|
||||||
users
|
users
|
||||||
|> List.map (fun user ->
|
|> List.map (fun user ->
|
||||||
let userId = user.userId.ToString "N"
|
let userId = flatGuid user.userId
|
||||||
let delAction = sprintf "/user/%s/delete" userId
|
let delAction = sprintf "/user/%s/delete" userId
|
||||||
let delPrompt = s.["Are you want to delete this {0}? This action cannot be undone.",
|
let delPrompt = s.["Are you want to delete this {0}? This action cannot be undone.",
|
||||||
(sprintf "%s (%s)" (s.["User"].Value.ToLower()) user.fullName)].Value
|
(sprintf "%s (%s)" (s.["User"].Value.ToLower()) user.fullName)].Value
|
||||||
|
@ -161,10 +161,8 @@ module Configure =
|
|||||||
let log = app.ApplicationServices.GetRequiredService<ILoggerFactory>()
|
let log = app.ApplicationServices.GetRequiredService<ILoggerFactory>()
|
||||||
(match env.IsDevelopment () with
|
(match env.IsDevelopment () with
|
||||||
| true ->
|
| true ->
|
||||||
log.AddConsole () |> ignore
|
|
||||||
app.UseDeveloperExceptionPage ()
|
app.UseDeveloperExceptionPage ()
|
||||||
| false ->
|
| false ->
|
||||||
log.AddConsole LogLevel.Warning |> ignore
|
|
||||||
try
|
try
|
||||||
use scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope ()
|
use scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope ()
|
||||||
scope.ServiceProvider.GetService<AppDbContext>().Database.Migrate ()
|
scope.ServiceProvider.GetService<AppDbContext>().Database.Migrate ()
|
||||||
@ -182,12 +180,10 @@ module Configure =
|
|||||||
/// The web application
|
/// The web application
|
||||||
module App =
|
module App =
|
||||||
|
|
||||||
open System
|
|
||||||
open System.IO
|
open System.IO
|
||||||
|
|
||||||
let exitCode = 0
|
[<EntryPoint>]
|
||||||
|
let main _ =
|
||||||
let CreateWebHostBuilder _ =
|
|
||||||
let contentRoot = Directory.GetCurrentDirectory ()
|
let contentRoot = Directory.GetCurrentDirectory ()
|
||||||
WebHostBuilder()
|
WebHostBuilder()
|
||||||
.UseContentRoot(contentRoot)
|
.UseContentRoot(contentRoot)
|
||||||
@ -196,10 +192,7 @@ module App =
|
|||||||
.UseWebRoot(Path.Combine (contentRoot, "wwwroot"))
|
.UseWebRoot(Path.Combine (contentRoot, "wwwroot"))
|
||||||
.ConfigureServices(Configure.services)
|
.ConfigureServices(Configure.services)
|
||||||
.ConfigureLogging(Configure.logging)
|
.ConfigureLogging(Configure.logging)
|
||||||
.Configure(Action<IApplicationBuilder> Configure.app)
|
.Configure(System.Action<IApplicationBuilder> Configure.app)
|
||||||
|
.Build()
|
||||||
[<EntryPoint>]
|
.Run ()
|
||||||
let main args =
|
0
|
||||||
CreateWebHostBuilder(args).Build().Run()
|
|
||||||
|
|
||||||
exitCode
|
|
||||||
|
@ -5,6 +5,7 @@ open Giraffe
|
|||||||
open PrayerTracker
|
open PrayerTracker
|
||||||
open PrayerTracker.Entities
|
open PrayerTracker.Entities
|
||||||
open PrayerTracker.ViewModels
|
open PrayerTracker.ViewModels
|
||||||
|
open PrayerTracker.Views.CommonFunctions
|
||||||
open System
|
open System
|
||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ let private findStats (db : AppDbContext) churchId =
|
|||||||
let! grps = db.CountGroupsByChurch churchId
|
let! grps = db.CountGroupsByChurch churchId
|
||||||
let! reqs = db.CountRequestsByChurch churchId
|
let! reqs = db.CountRequestsByChurch churchId
|
||||||
let! usrs = db.CountUsersByChurch churchId
|
let! usrs = db.CountUsersByChurch churchId
|
||||||
return (churchId.ToString "N"), { smallGroups = grps; prayerRequests = reqs; users = usrs }
|
return flatGuid churchId, { smallGroups = grps; prayerRequests = reqs; users = usrs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
module PrayerTracker.Extensions
|
module PrayerTracker.Extensions
|
||||||
|
|
||||||
open Microsoft.AspNetCore.Http
|
open Microsoft.AspNetCore.Http
|
||||||
|
open Microsoft.FSharpLu
|
||||||
open Newtonsoft.Json
|
open Newtonsoft.Json
|
||||||
open PrayerTracker.Entities
|
open PrayerTracker.Entities
|
||||||
open PrayerTracker.ViewModels
|
open PrayerTracker.ViewModels
|
||||||
@ -19,14 +20,14 @@ type ISession with
|
|||||||
| v -> JsonConvert.DeserializeObject<'T> v
|
| v -> JsonConvert.DeserializeObject<'T> v
|
||||||
|
|
||||||
member this.GetSmallGroup () =
|
member this.GetSmallGroup () =
|
||||||
this.GetObject<SmallGroup> Key.Session.currentGroup |> optRec
|
this.GetObject<SmallGroup> Key.Session.currentGroup |> Option.fromObject
|
||||||
member this.SetSmallGroup (group : SmallGroup option) =
|
member this.SetSmallGroup (group : SmallGroup option) =
|
||||||
match group with
|
match group with
|
||||||
| Some g -> this.SetObject Key.Session.currentGroup g
|
| Some g -> this.SetObject Key.Session.currentGroup g
|
||||||
| None -> this.Remove Key.Session.currentGroup
|
| None -> this.Remove Key.Session.currentGroup
|
||||||
|
|
||||||
member this.GetUser () =
|
member this.GetUser () =
|
||||||
this.GetObject<User> Key.Session.currentUser |> optRec
|
this.GetObject<User> Key.Session.currentUser |> Option.fromObject
|
||||||
member this.SetUser (user: User option) =
|
member this.SetUser (user: User option) =
|
||||||
match user with
|
match user with
|
||||||
| Some u -> this.SetObject Key.Session.currentUser u
|
| Some u -> this.SetObject Key.Session.currentUser u
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
<AssemblyVersion>7.1.0.0</AssemblyVersion>
|
<AssemblyVersion>7.2.0.0</AssemblyVersion>
|
||||||
<FileVersion>7.0.0.0</FileVersion>
|
<FileVersion>7.0.0.0</FileVersion>
|
||||||
<Authors></Authors>
|
<Authors></Authors>
|
||||||
<Company>Bit Badger Solutions</Company>
|
<Company>Bit Badger Solutions</Company>
|
||||||
@ -28,11 +28,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Giraffe" Version="3.1.0" />
|
<PackageReference Include="Giraffe" Version="3.6.0" />
|
||||||
<PackageReference Include="Giraffe.TokenRouter" Version="1.0.0" />
|
<PackageReference Include="Giraffe.TokenRouter" Version="1.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.5" />
|
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.5" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.2" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="FSharp.Core" Version="4.5.2" />
|
<PackageReference Update="FSharp.Core" Version="4.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -9,6 +9,7 @@ open PrayerTracker
|
|||||||
open PrayerTracker.Cookies
|
open PrayerTracker.Cookies
|
||||||
open PrayerTracker.Entities
|
open PrayerTracker.Entities
|
||||||
open PrayerTracker.ViewModels
|
open PrayerTracker.ViewModels
|
||||||
|
open PrayerTracker.Views.CommonFunctions
|
||||||
open System
|
open System
|
||||||
open System.Threading.Tasks
|
open System.Threading.Tasks
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ let logOn (groupId : SmallGroupId option) : HttpHandler =
|
|||||||
let startTicks = DateTime.Now.Ticks
|
let startTicks = DateTime.Now.Ticks
|
||||||
task {
|
task {
|
||||||
let! grps = ctx.dbContext().ProtectedGroups ()
|
let! grps = ctx.dbContext().ProtectedGroups ()
|
||||||
let grpId = match groupId with Some gid -> gid.ToString "N" | None -> ""
|
let grpId = match groupId with Some gid -> flatGuid gid | None -> ""
|
||||||
return!
|
return!
|
||||||
{ viewInfo ctx startTicks with helpLink = Help.logOn }
|
{ viewInfo ctx startTicks with helpLink = Help.logOn }
|
||||||
|> Views.SmallGroup.logOn grps grpId ctx
|
|> Views.SmallGroup.logOn grps grpId ctx
|
||||||
@ -162,7 +163,7 @@ let logOnSubmit : HttpHandler =
|
|||||||
return! redirectTo false "/prayer-requests/view" next ctx
|
return! redirectTo false "/prayer-requests/view" next ctx
|
||||||
| None ->
|
| None ->
|
||||||
addError ctx s.["Password incorrect - login unsuccessful"]
|
addError ctx s.["Password incorrect - login unsuccessful"]
|
||||||
return! redirectTo false (sprintf "/small-group/log-on/%s" (m.smallGroupId.ToString "N")) next ctx
|
return! redirectTo false (sprintf "/small-group/log-on/%s" (flatGuid m.smallGroupId)) next ctx
|
||||||
| Error e -> return! bindError e next ctx
|
| Error e -> return! bindError e next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ open PrayerTracker
|
|||||||
open PrayerTracker.Cookies
|
open PrayerTracker.Cookies
|
||||||
open PrayerTracker.Entities
|
open PrayerTracker.Entities
|
||||||
open PrayerTracker.ViewModels
|
open PrayerTracker.ViewModels
|
||||||
|
open PrayerTracker.Views.CommonFunctions
|
||||||
open System
|
open System
|
||||||
open System.Collections.Generic
|
open System.Collections.Generic
|
||||||
open System.Net
|
open System.Net
|
||||||
@ -270,7 +271,7 @@ let save : HttpHandler =
|
|||||||
|> Some
|
|> Some
|
||||||
}
|
}
|
||||||
|> addUserMessage ctx
|
|> addUserMessage ctx
|
||||||
return! redirectTo false (sprintf "/user/%s/small-groups" (u.userId.ToString "N")) next ctx
|
return! redirectTo false (sprintf "/user/%s/small-groups" (flatGuid u.userId)) next ctx
|
||||||
| false ->
|
| false ->
|
||||||
addInfo ctx s.["Successfully {0} user", s.["Updated"].Value.ToLower ()]
|
addInfo ctx s.["Successfully {0} user", s.["Updated"].Value.ToLower ()]
|
||||||
return! redirectTo false "/users" next ctx
|
return! redirectTo false "/users" next ctx
|
||||||
@ -292,7 +293,7 @@ let saveGroups : HttpHandler =
|
|||||||
match Seq.length m.smallGroups with
|
match Seq.length m.smallGroups with
|
||||||
| 0 ->
|
| 0 ->
|
||||||
addError ctx s.["You must select at least one group to assign"]
|
addError ctx s.["You must select at least one group to assign"]
|
||||||
return! redirectTo false (sprintf "/user/%s/small-groups" (m.userId.ToString "N")) next ctx
|
return! redirectTo false (sprintf "/user/%s/small-groups" (flatGuid m.userId)) next ctx
|
||||||
| _ ->
|
| _ ->
|
||||||
let db = ctx.dbContext ()
|
let db = ctx.dbContext ()
|
||||||
let! user = db.TryUserByIdWithGroups m.userId
|
let! user = db.TryUserByIdWithGroups m.userId
|
||||||
@ -330,12 +331,7 @@ let smallGroups userId : HttpHandler =
|
|||||||
match user with
|
match user with
|
||||||
| Some u ->
|
| Some u ->
|
||||||
let! grps = db.GroupList ()
|
let! grps = db.GroupList ()
|
||||||
let curGroups =
|
let curGroups = u.smallGroups |> Seq.map (fun g -> flatGuid g.smallGroupId) |> List.ofSeq
|
||||||
seq {
|
|
||||||
for g in u.smallGroups do
|
|
||||||
yield g.smallGroupId.ToString "N"
|
|
||||||
}
|
|
||||||
|> List.ofSeq
|
|
||||||
return!
|
return!
|
||||||
viewInfo ctx startTicks
|
viewInfo ctx startTicks
|
||||||
|> Views.User.assignGroups (AssignGroups.fromUser u) grps curGroups ctx
|
|> Views.User.assignGroups (AssignGroups.fromUser u) grps curGroups ctx
|
||||||
|
Loading…
Reference in New Issue
Block a user