Version 3 #67
@ -116,20 +116,20 @@ module private Helpers =
|
|||||||
|
|
||||||
|
|
||||||
/// Retrieve a request, including its history and notes, by its ID and user ID
|
/// Retrieve a request, including its history and notes, by its ID and user ID
|
||||||
let tryFullRequestById reqId userId (db : LiteDatabase) = task {
|
let tryFullRequestById reqId userId (db : LiteDatabase) = backgroundTask {
|
||||||
let! req = db.requests.Find (Query.EQ ("_id", RequestId.toString reqId)) |> firstAsync
|
let! req = db.requests.Find (Query.EQ ("_id", RequestId.toString reqId)) |> firstAsync
|
||||||
return match box req with null -> None | _ when req.userId = userId -> Some req | _ -> None
|
return match box req with null -> None | _ when req.userId = userId -> Some req | _ -> None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a history entry
|
/// Add a history entry
|
||||||
let addHistory reqId userId hist db = task {
|
let addHistory reqId userId hist db = backgroundTask {
|
||||||
match! tryFullRequestById reqId userId db with
|
match! tryFullRequestById reqId userId db with
|
||||||
| Some req -> do! doUpdate db { req with history = hist :: req.history }
|
| Some req -> do! doUpdate db { req with history = hist :: req.history }
|
||||||
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a note
|
/// Add a note
|
||||||
let addNote reqId userId note db = task {
|
let addNote reqId userId note db = backgroundTask {
|
||||||
match! tryFullRequestById reqId userId db with
|
match! tryFullRequestById reqId userId db with
|
||||||
| Some req -> do! doUpdate db { req with notes = note :: req.notes }
|
| Some req -> do! doUpdate db { req with notes = note :: req.notes }
|
||||||
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
||||||
@ -140,7 +140,7 @@ let addRequest (req : Request) (db : LiteDatabase) =
|
|||||||
db.requests.Insert req |> ignore
|
db.requests.Insert req |> ignore
|
||||||
|
|
||||||
/// Retrieve all answered requests for the given user
|
/// Retrieve all answered requests for the given user
|
||||||
let answeredRequests userId (db : LiteDatabase) = task {
|
let answeredRequests userId (db : LiteDatabase) = backgroundTask {
|
||||||
let! reqs = db.requests.Find (Query.EQ ("userId", UserId.toString userId)) |> toListAsync
|
let! reqs = db.requests.Find (Query.EQ ("userId", UserId.toString userId)) |> toListAsync
|
||||||
return
|
return
|
||||||
reqs
|
reqs
|
||||||
@ -151,7 +151,7 @@ let answeredRequests userId (db : LiteDatabase) = task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the user's current journal
|
/// Retrieve the user's current journal
|
||||||
let journalByUserId userId (db : LiteDatabase) = task {
|
let journalByUserId userId (db : LiteDatabase) = backgroundTask {
|
||||||
let! jrnl = db.requests.Find (Query.EQ ("userId", UserId.toString userId)) |> toListAsync
|
let! jrnl = db.requests.Find (Query.EQ ("userId", UserId.toString userId)) |> toListAsync
|
||||||
return
|
return
|
||||||
jrnl
|
jrnl
|
||||||
@ -162,38 +162,38 @@ let journalByUserId userId (db : LiteDatabase) = task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a request by its ID and user ID (without notes and history)
|
/// Retrieve a request by its ID and user ID (without notes and history)
|
||||||
let tryRequestById reqId userId db = task {
|
let tryRequestById reqId userId db = backgroundTask {
|
||||||
let! req = tryFullRequestById reqId userId db
|
let! req = tryFullRequestById reqId userId db
|
||||||
return req |> Option.map (fun r -> { r with history = []; notes = [] })
|
return req |> Option.map (fun r -> { r with history = []; notes = [] })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve notes for a request by its ID and user ID
|
/// Retrieve notes for a request by its ID and user ID
|
||||||
let notesById reqId userId (db : LiteDatabase) = task {
|
let notesById reqId userId (db : LiteDatabase) = backgroundTask {
|
||||||
match! tryFullRequestById reqId userId db with | Some req -> return req.notes | None -> return []
|
match! tryFullRequestById reqId userId db with | Some req -> return req.notes | None -> return []
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve a journal request by its ID and user ID
|
/// Retrieve a journal request by its ID and user ID
|
||||||
let tryJournalById reqId userId (db : LiteDatabase) = task {
|
let tryJournalById reqId userId (db : LiteDatabase) = backgroundTask {
|
||||||
let! req = tryFullRequestById reqId userId db
|
let! req = tryFullRequestById reqId userId db
|
||||||
return req |> Option.map JournalRequest.ofRequestLite
|
return req |> Option.map JournalRequest.ofRequestLite
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the recurrence for a request
|
/// Update the recurrence for a request
|
||||||
let updateRecurrence reqId userId recurType recurCount db = task {
|
let updateRecurrence reqId userId recurType recurCount db = backgroundTask {
|
||||||
match! tryFullRequestById reqId userId db with
|
match! tryFullRequestById reqId userId db with
|
||||||
| Some req -> do! doUpdate db { req with recurType = recurType; recurCount = recurCount }
|
| Some req -> do! doUpdate db { req with recurType = recurType; recurCount = recurCount }
|
||||||
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a snoozed request
|
/// Update a snoozed request
|
||||||
let updateSnoozed reqId userId until db = task {
|
let updateSnoozed reqId userId until db = backgroundTask {
|
||||||
match! tryFullRequestById reqId userId db with
|
match! tryFullRequestById reqId userId db with
|
||||||
| Some req -> do! doUpdate db { req with snoozedUntil = until; showAfter = until }
|
| Some req -> do! doUpdate db { req with snoozedUntil = until; showAfter = until }
|
||||||
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the "show after" timestamp for a request
|
/// Update the "show after" timestamp for a request
|
||||||
let updateShowAfter reqId userId showAfter db = task {
|
let updateShowAfter reqId userId showAfter db = backgroundTask {
|
||||||
match! tryFullRequestById reqId userId db with
|
match! tryFullRequestById reqId userId db with
|
||||||
| Some req -> do! doUpdate db { req with showAfter = showAfter }
|
| Some req -> do! doUpdate db { req with showAfter = showAfter }
|
||||||
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
| None -> invalidOp $"{RequestId.toString reqId} not found"
|
||||||
|
@ -17,7 +17,7 @@ module private LogOnHelpers =
|
|||||||
|
|
||||||
/// Log on, optionally specifying a redirected URL once authentication is complete
|
/// Log on, optionally specifying a redirected URL once authentication is complete
|
||||||
let logOn url : HttpHandler =
|
let logOn url : HttpHandler =
|
||||||
fun next ctx -> task {
|
fun next ctx -> backgroundTask {
|
||||||
match url with
|
match url with
|
||||||
| Some it ->
|
| Some it ->
|
||||||
do! ctx.ChallengeAsync ("Auth0", AuthenticationProperties (RedirectUri = it))
|
do! ctx.ChallengeAsync ("Auth0", AuthenticationProperties (RedirectUri = it))
|
||||||
@ -102,7 +102,7 @@ module private Helpers =
|
|||||||
/// Render a component result
|
/// Render a component result
|
||||||
let renderComponent nodes : HttpHandler =
|
let renderComponent nodes : HttpHandler =
|
||||||
noResponseCaching
|
noResponseCaching
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
return! ctx.WriteHtmlStringAsync (ViewEngine.RenderView.AsString.htmlNodes nodes)
|
return! ctx.WriteHtmlStringAsync (ViewEngine.RenderView.AsString.htmlNodes nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ module private Helpers =
|
|||||||
|
|
||||||
/// Composable handler to write a view to the output
|
/// Composable handler to write a view to the output
|
||||||
let writeView view : HttpHandler =
|
let writeView view : HttpHandler =
|
||||||
fun next ctx -> task {
|
fun next ctx -> backgroundTask {
|
||||||
return! ctx.WriteHtmlViewAsync view
|
return! ctx.WriteHtmlViewAsync view
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +167,10 @@ module private Helpers =
|
|||||||
let withSuccessMessage : string -> HttpHandler =
|
let withSuccessMessage : string -> HttpHandler =
|
||||||
sprintf "success|||%s" >> setHttpHeader "X-Toast"
|
sprintf "success|||%s" >> setHttpHeader "X-Toast"
|
||||||
|
|
||||||
|
/// Hide a modal window when the response is sent
|
||||||
|
let hideModal (name : string) : HttpHandler =
|
||||||
|
setHttpHeader "X-Hide-Modal" name
|
||||||
|
|
||||||
|
|
||||||
/// Strongly-typed models for post requests
|
/// Strongly-typed models for post requests
|
||||||
module Models =
|
module Models =
|
||||||
@ -213,7 +217,7 @@ module Components =
|
|||||||
// GET /components/journal-items
|
// GET /components/journal-items
|
||||||
let journalItems : HttpHandler =
|
let journalItems : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let shouldShow now r = now > Ticks.toLong r.snoozedUntil && now > Ticks.toLong r.showAfter
|
let shouldShow now r = now > Ticks.toLong r.snoozedUntil && now > Ticks.toLong r.showAfter
|
||||||
let! jrnl = Data.journalByUserId (userId ctx) (db ctx)
|
let! jrnl = Data.journalByUserId (userId ctx) (db ctx)
|
||||||
let shown = jrnl |> List.filter (shouldShow ((jsNow >> Ticks.toLong) ()))
|
let shown = jrnl |> List.filter (shouldShow ((jsNow >> Ticks.toLong) ()))
|
||||||
@ -223,7 +227,7 @@ module Components =
|
|||||||
// GET /components/request-item/[req-id]
|
// GET /components/request-item/[req-id]
|
||||||
let requestItem reqId : HttpHandler =
|
let requestItem reqId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
match! Data.tryJournalById (RequestId.ofString reqId) (userId ctx) (db ctx) with
|
match! Data.tryJournalById (RequestId.ofString reqId) (userId ctx) (db ctx) with
|
||||||
| Some req -> return! renderComponent [ Views.Request.reqListItem req ] next ctx
|
| Some req -> return! renderComponent [ Views.Request.reqListItem req ] next ctx
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
@ -237,7 +241,7 @@ module Components =
|
|||||||
/// GET /components/request/[req-id]/notes
|
/// GET /components/request/[req-id]/notes
|
||||||
let notes requestId : HttpHandler =
|
let notes requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let! notes = Data.notesById (RequestId.ofString requestId) (userId ctx) (db ctx)
|
let! notes = Data.notesById (RequestId.ofString requestId) (userId ctx) (db ctx)
|
||||||
return! renderComponent (Views.Request.notes notes) next ctx
|
return! renderComponent (Views.Request.notes notes) next ctx
|
||||||
}
|
}
|
||||||
@ -257,7 +261,7 @@ module Journal =
|
|||||||
// GET /journal
|
// GET /journal
|
||||||
let journal : HttpHandler =
|
let journal : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let usr =
|
let usr =
|
||||||
ctx.User.Claims
|
ctx.User.Claims
|
||||||
|> Seq.tryFind (fun c -> c.Type = ClaimTypes.GivenName)
|
|> Seq.tryFind (fun c -> c.Type = ClaimTypes.GivenName)
|
||||||
@ -286,7 +290,7 @@ module Request =
|
|||||||
// GET /request/[req-id]/edit
|
// GET /request/[req-id]/edit
|
||||||
let edit requestId : HttpHandler =
|
let edit requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let returnTo =
|
let returnTo =
|
||||||
match ctx.Request.Headers.Referer.[0] with
|
match ctx.Request.Headers.Referer.[0] with
|
||||||
| it when it.EndsWith "/active" -> "active"
|
| it when it.EndsWith "/active" -> "active"
|
||||||
@ -305,7 +309,7 @@ module Request =
|
|||||||
// PATCH /request/[req-id]/prayed
|
// PATCH /request/[req-id]/prayed
|
||||||
let prayed requestId : HttpHandler =
|
let prayed requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
let reqId = RequestId.ofString requestId
|
let reqId = RequestId.ofString requestId
|
||||||
@ -323,26 +327,26 @@ module Request =
|
|||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
/// POST /api/request/[req-id]/note
|
/// POST /request/[req-id]/note
|
||||||
let addNote requestId : HttpHandler =
|
let addNote requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
let reqId = RequestId.ofString requestId
|
let reqId = RequestId.ofString requestId
|
||||||
match! Data.tryRequestById reqId usrId db with
|
match! Data.tryRequestById reqId usrId db with
|
||||||
| Some _ ->
|
| Some _ ->
|
||||||
let! notes = ctx.BindJsonAsync<Models.NoteEntry> ()
|
let! notes = ctx.BindFormAsync<Models.NoteEntry> ()
|
||||||
do! Data.addNote reqId usrId { asOf = jsNow (); notes = notes.notes } db
|
do! Data.addNote reqId usrId { asOf = jsNow (); notes = notes.notes } db
|
||||||
do! db.saveChanges ()
|
do! db.saveChanges ()
|
||||||
return! created next ctx
|
return! (withSuccessMessage "Added Notes" >=> hideModal "notes" >=> created) next ctx
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET /requests/active
|
// GET /requests/active
|
||||||
let active : HttpHandler =
|
let active : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let! reqs = Data.journalByUserId (userId ctx) (db ctx)
|
let! reqs = Data.journalByUserId (userId ctx) (db ctx)
|
||||||
return! partial "Active Requests" (Views.Request.active reqs) next ctx
|
return! partial "Active Requests" (Views.Request.active reqs) next ctx
|
||||||
}
|
}
|
||||||
@ -350,7 +354,7 @@ module Request =
|
|||||||
// GET /requests/snoozed
|
// GET /requests/snoozed
|
||||||
let snoozed : HttpHandler =
|
let snoozed : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let! reqs = Data.journalByUserId (userId ctx) (db ctx)
|
let! reqs = Data.journalByUserId (userId ctx) (db ctx)
|
||||||
let now = (jsNow >> Ticks.toLong) ()
|
let now = (jsNow >> Ticks.toLong) ()
|
||||||
let snoozed = reqs |> List.filter (fun r -> Ticks.toLong r.snoozedUntil > now)
|
let snoozed = reqs |> List.filter (fun r -> Ticks.toLong r.snoozedUntil > now)
|
||||||
@ -360,7 +364,7 @@ module Request =
|
|||||||
// GET /requests/answered
|
// GET /requests/answered
|
||||||
let answered : HttpHandler =
|
let answered : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let! reqs = Data.answeredRequests (userId ctx) (db ctx)
|
let! reqs = Data.answeredRequests (userId ctx) (db ctx)
|
||||||
return! partial "Answered Requests" (Views.Request.answered reqs) next ctx
|
return! partial "Answered Requests" (Views.Request.answered reqs) next ctx
|
||||||
}
|
}
|
||||||
@ -368,7 +372,7 @@ module Request =
|
|||||||
/// GET /api/request/[req-id]
|
/// GET /api/request/[req-id]
|
||||||
let get requestId : HttpHandler =
|
let get requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
match! Data.tryJournalById (RequestId.ofString requestId) (userId ctx) (db ctx) with
|
match! Data.tryJournalById (RequestId.ofString requestId) (userId ctx) (db ctx) with
|
||||||
| Some req -> return! json req next ctx
|
| Some req -> return! json req next ctx
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
@ -377,7 +381,7 @@ module Request =
|
|||||||
// GET /request/[req-id]/full
|
// GET /request/[req-id]/full
|
||||||
let getFull requestId : HttpHandler =
|
let getFull requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
match! Data.tryFullRequestById (RequestId.ofString requestId) (userId ctx) (db ctx) with
|
match! Data.tryFullRequestById (RequestId.ofString requestId) (userId ctx) (db ctx) with
|
||||||
| Some req -> return! partial "Prayer Request" (Views.Request.full req) next ctx
|
| Some req -> return! partial "Prayer Request" (Views.Request.full req) next ctx
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
@ -386,7 +390,7 @@ module Request =
|
|||||||
// PATCH /request/[req-id]/show
|
// PATCH /request/[req-id]/show
|
||||||
let show requestId : HttpHandler =
|
let show requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
let reqId = RequestId.ofString requestId
|
let reqId = RequestId.ofString requestId
|
||||||
@ -401,7 +405,7 @@ module Request =
|
|||||||
/// PATCH /api/request/[req-id]/snooze
|
/// PATCH /api/request/[req-id]/snooze
|
||||||
let snooze requestId : HttpHandler =
|
let snooze requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
let reqId = RequestId.ofString requestId
|
let reqId = RequestId.ofString requestId
|
||||||
@ -417,7 +421,7 @@ module Request =
|
|||||||
// PATCH /request/[req-id]/cancel-snooze
|
// PATCH /request/[req-id]/cancel-snooze
|
||||||
let cancelSnooze requestId : HttpHandler =
|
let cancelSnooze requestId : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
let reqId = RequestId.ofString requestId
|
let reqId = RequestId.ofString requestId
|
||||||
@ -437,7 +441,7 @@ module Request =
|
|||||||
// POST /request
|
// POST /request
|
||||||
let add : HttpHandler =
|
let add : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let! form = ctx.BindModelAsync<Models.Request> ()
|
let! form = ctx.BindModelAsync<Models.Request> ()
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
@ -466,7 +470,7 @@ module Request =
|
|||||||
// PATCH /request
|
// PATCH /request
|
||||||
let update : HttpHandler =
|
let update : HttpHandler =
|
||||||
requiresAuthentication Error.notAuthorized
|
requiresAuthentication Error.notAuthorized
|
||||||
>=> fun next ctx -> task {
|
>=> fun next ctx -> backgroundTask {
|
||||||
let! form = ctx.BindModelAsync<Models.Request> ()
|
let! form = ctx.BindModelAsync<Models.Request> ()
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
@ -553,6 +557,7 @@ let routes =
|
|||||||
]
|
]
|
||||||
POST [
|
POST [
|
||||||
route "" Request.add
|
route "" Request.add
|
||||||
|
routef "/%s/note" Request.addNote
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
subRoute "/user/" [
|
subRoute "/user/" [
|
||||||
@ -572,10 +577,5 @@ let routes =
|
|||||||
routef "/%s/snooze" Request.snooze
|
routef "/%s/snooze" Request.snooze
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
POST [
|
|
||||||
subRoute "request" [
|
|
||||||
routef "/%s/note" Request.addNote
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -75,7 +75,9 @@ let journal user = article [ _class "container-fluid mt-3" ] [
|
|||||||
]
|
]
|
||||||
div [ _class "modal-body"; _id "notesBody" ] [ ]
|
div [ _class "modal-body"; _id "notesBody" ] [ ]
|
||||||
div [ _class "modal-footer" ] [
|
div [ _class "modal-footer" ] [
|
||||||
button [ _type "button"; _class "btn btn-secondary"; _data "bs-dismiss" "modal" ] [ str "Close" ]
|
button [ _type "button"; _id "notesDismiss"; _class "btn btn-secondary"; _data "bs-dismiss" "modal" ] [
|
||||||
|
str "Close"
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -102,12 +104,23 @@ let journalItems items =
|
|||||||
/// The notes edit modal body
|
/// The notes edit modal body
|
||||||
let notesEdit requestId =
|
let notesEdit requestId =
|
||||||
let reqId = RequestId.toString requestId
|
let reqId = RequestId.toString requestId
|
||||||
[ form [ _hxPost $"/request/{reqId}/note"; _hxTarget "#top" ] [
|
[ form [ _hxPost $"/request/{reqId}/note" ] [
|
||||||
str "TODO"
|
div [ _class "form-floating pb-3" ] [
|
||||||
button [ _type "submit"; _class "btn btn-primary" ] [ str "Add Notes" ]
|
textarea [
|
||||||
|
_id "notes"
|
||||||
|
_name "notes"
|
||||||
|
_class "form-control"
|
||||||
|
_style "min-height: 8rem;"
|
||||||
|
_placeholder "Notes"
|
||||||
|
_autofocus; _required
|
||||||
|
] [ ]
|
||||||
|
label [ _for "notes" ] [ str "Notes" ]
|
||||||
]
|
]
|
||||||
|
p [ _class "text-end" ] [ button [ _type "submit"; _class "btn btn-primary" ] [ str "Add Notes" ] ]
|
||||||
|
]
|
||||||
|
hr [ _style "margin: .5rem -1rem" ]
|
||||||
div [ _id "priorNotes" ] [
|
div [ _id "priorNotes" ] [
|
||||||
p [ _class "text-center pt-5" ] [
|
p [ _class "text-center pt-3" ] [
|
||||||
button [
|
button [
|
||||||
_type "button"
|
_type "button"
|
||||||
_class "btn btn-secondary"
|
_class "btn btn-secondary"
|
||||||
|
@ -263,8 +263,7 @@ let edit (req : JournalRequest) returnTo isNew =
|
|||||||
/// Display a list of notes for a request
|
/// Display a list of notes for a request
|
||||||
let notes notes =
|
let notes notes =
|
||||||
let toItem (note : Note) = p [] [ small [ _class "text-muted" ] [ relativeDate note.asOf ]; br []; str note.notes ]
|
let toItem (note : Note) = p [] [ small [ _class "text-muted" ] [ relativeDate note.asOf ]; br []; str note.notes ]
|
||||||
[ hr [ _style "margin: .5rem -1rem" ]
|
[ p [ _class "text-center" ] [ strong [] [ str "Prior Notes for This Request" ] ]
|
||||||
p [ _class "text-center" ] [ strong [] [ str "Prior Notes for This Request" ] ]
|
|
||||||
match notes with
|
match notes with
|
||||||
| [] -> p [ _class "text-center text-muted" ] [ str "There are no prior notes for this request" ]
|
| [] -> p [ _class "text-center text-muted" ] [ str "There are no prior notes for this request" ]
|
||||||
| _ -> yield! notes |> List.map toItem
|
| _ -> yield! notes |> List.map toItem
|
||||||
|
@ -66,19 +66,6 @@ const mpj = {
|
|||||||
const isDisabled = target.value === "Immediate"
|
const isDisabled = target.value === "Immediate"
|
||||||
;["recurCount", "recurInterval"].forEach(it => document.getElementById(it).disabled = isDisabled)
|
;["recurCount", "recurInterval"].forEach(it => document.getElementById(it).disabled = isDisabled)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/** Script for the journal page */
|
|
||||||
journal: {
|
|
||||||
/**
|
|
||||||
* Set up the journal page modals
|
|
||||||
*/
|
|
||||||
setUp () {
|
|
||||||
document.getElementById("notesModal").addEventListener("show.bs.modal", function (event) {
|
|
||||||
const reqId = event.relatedTarget.getAttribute("data-request-id")
|
|
||||||
document.getElementById("notesForm").setAttribute("action", `/request/${reqId}/note`)
|
|
||||||
document.getElementById("notesLoad").setAttribute("hx-get", `/components/request/${reqId}/notes`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,5 +75,8 @@ htmx.on("htmx:afterOnLoad", function (evt) {
|
|||||||
if (hdrs.indexOf("x-toast") >= 0) {
|
if (hdrs.indexOf("x-toast") >= 0) {
|
||||||
mpj.showToast(evt.detail.xhr.getResponseHeader("x-toast"))
|
mpj.showToast(evt.detail.xhr.getResponseHeader("x-toast"))
|
||||||
}
|
}
|
||||||
|
// Hide a modal window if requested
|
||||||
|
if (hdrs.indexOf("x-hide-modal") >= 0) {
|
||||||
|
document.getElementById(evt.detail.xhr.getResponseHeader("x-hide-modal") + "Dismiss").click()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user