API/app working nicely with RavenDB
time to v2 the app...
This commit is contained in:
parent
c587d9772f
commit
d0456ab886
@ -1,17 +1,14 @@
|
|||||||
namespace MyPrayerJournal
|
namespace MyPrayerJournal
|
||||||
|
|
||||||
open FSharp.Control.Tasks.V2.ContextInsensitive
|
|
||||||
open Microsoft.FSharpLu
|
|
||||||
open Newtonsoft.Json
|
|
||||||
open Raven.Client.Documents
|
|
||||||
open Raven.Client.Documents.Indexes
|
|
||||||
open Raven.Client.Documents.Linq
|
|
||||||
open System
|
open System
|
||||||
open System.Collections.Generic
|
open System.Collections.Generic
|
||||||
|
|
||||||
/// JSON converters for various DUs
|
/// JSON converters for various DUs
|
||||||
module Converters =
|
module Converters =
|
||||||
|
|
||||||
|
open Microsoft.FSharpLu.Json
|
||||||
|
open Newtonsoft.Json
|
||||||
|
|
||||||
/// JSON converter for request IDs
|
/// JSON converter for request IDs
|
||||||
type RequestIdJsonConverter () =
|
type RequestIdJsonConverter () =
|
||||||
inherit JsonConverter<RequestId> ()
|
inherit JsonConverter<RequestId> ()
|
||||||
@ -36,30 +33,28 @@ module Converters =
|
|||||||
override __.ReadJson(reader: JsonReader, _ : Type, _ : Ticks, _ : bool, _ : JsonSerializer) =
|
override __.ReadJson(reader: JsonReader, _ : Type, _ : Ticks, _ : bool, _ : JsonSerializer) =
|
||||||
(string >> int64 >> Ticks) reader.Value
|
(string >> int64 >> Ticks) reader.Value
|
||||||
|
|
||||||
/// A sequence of all custom converters for myPrayerJournal
|
/// A sequence of all custom converters needed for myPrayerJournal
|
||||||
let all : JsonConverter seq =
|
let all : JsonConverter seq =
|
||||||
seq {
|
seq {
|
||||||
yield RequestIdJsonConverter ()
|
yield RequestIdJsonConverter ()
|
||||||
yield UserIdJsonConverter ()
|
yield UserIdJsonConverter ()
|
||||||
yield TicksJsonConverter ()
|
yield TicksJsonConverter ()
|
||||||
|
yield CompactUnionJsonConverter true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// RavenDB index declarations
|
/// RavenDB index declarations
|
||||||
module Indexes =
|
module Indexes =
|
||||||
|
|
||||||
/// Index requests by user ID
|
open Raven.Client.Documents.Indexes
|
||||||
type Requests_ByUserId () as this =
|
|
||||||
inherit AbstractJavaScriptIndexCreationTask ()
|
|
||||||
do
|
|
||||||
this.Maps <- HashSet<string> [ "docs.Requests.Select(req => new { userId = req.userId })" ]
|
|
||||||
|
|
||||||
/// Index requests for a journal view
|
/// Index requests for a journal view
|
||||||
type Requests_AsJournal () as this =
|
type Requests_AsJournal () as this =
|
||||||
inherit AbstractJavaScriptIndexCreationTask ()
|
inherit AbstractJavaScriptIndexCreationTask ()
|
||||||
do
|
do
|
||||||
this.Maps <- HashSet<string> [
|
this.Maps <- HashSet<string> [
|
||||||
"docs.Requests.Select(req => new {
|
"""docs.Requests.Select(req => new {
|
||||||
requestId = req.Id,
|
requestId = req.Id.Replace("Requests/", ""),
|
||||||
userId = req.userId,
|
userId = req.userId,
|
||||||
text = req.history.Where(hist => hist.text != null).OrderByDescending(hist => hist.asOf).First().text,
|
text = req.history.Where(hist => hist.text != null).OrderByDescending(hist => hist.asOf).First().text,
|
||||||
asOf = req.history.OrderByDescending(hist => hist.asOf).First().asOf,
|
asOf = req.history.OrderByDescending(hist => hist.asOf).First().asOf,
|
||||||
@ -68,10 +63,11 @@ module Indexes =
|
|||||||
showAfter = req.showAfter,
|
showAfter = req.showAfter,
|
||||||
recurType = req.recurType,
|
recurType = req.recurType,
|
||||||
recurCount = req.recurCount
|
recurCount = req.recurCount
|
||||||
})"
|
})"""
|
||||||
]
|
]
|
||||||
this.Fields <-
|
this.Fields <-
|
||||||
[ "text", IndexFieldOptions (Storage = Nullable FieldStorage.Yes)
|
[ "requestId", IndexFieldOptions (Storage = Nullable FieldStorage.Yes)
|
||||||
|
"text", IndexFieldOptions (Storage = Nullable FieldStorage.Yes)
|
||||||
"asOf", IndexFieldOptions (Storage = Nullable FieldStorage.Yes)
|
"asOf", IndexFieldOptions (Storage = Nullable FieldStorage.Yes)
|
||||||
"lastStatus", IndexFieldOptions (Storage = Nullable FieldStorage.Yes)
|
"lastStatus", IndexFieldOptions (Storage = Nullable FieldStorage.Yes)
|
||||||
]
|
]
|
||||||
@ -79,39 +75,14 @@ module Indexes =
|
|||||||
|> Dictionary<string, IndexFieldOptions>
|
|> Dictionary<string, IndexFieldOptions>
|
||||||
|
|
||||||
|
|
||||||
/// Extensions on the IAsyncDocumentSession interface to support our data manipulation needs
|
|
||||||
[<AutoOpen>]
|
|
||||||
module Extensions =
|
|
||||||
|
|
||||||
open Indexes
|
|
||||||
open Raven.Client.Documents.Commands.Batches
|
|
||||||
open Raven.Client.Documents.Operations
|
|
||||||
open Raven.Client.Documents.Session
|
|
||||||
|
|
||||||
/// Format an RQL query by a strongly-typed index
|
|
||||||
let fromIndex (typ : Type) =
|
|
||||||
typ.Name.Replace ("_", "/") |> sprintf "from index '%s'"
|
|
||||||
|
|
||||||
/// Utility method to create a patch request to push an item on the end of a list
|
|
||||||
let listPush<'T> listName docId (item : 'T) =
|
|
||||||
let r = PatchRequest()
|
|
||||||
r.Script <- sprintf "this.%s.push(args.Item)" listName
|
|
||||||
r.Values.["Item"] <- item
|
|
||||||
PatchCommandData (docId, null, r, null)
|
|
||||||
|
|
||||||
/// Utility method to create a patch to update a single field
|
|
||||||
// TODO: think we need to include quotes if it's a string
|
|
||||||
let fieldUpdate<'T> fieldName docId (item : 'T) =
|
|
||||||
let r = PatchRequest()
|
|
||||||
r.Script <- sprintf "this.%s = args.Item" fieldName
|
|
||||||
r.Values.["Item"] <- item
|
|
||||||
PatchCommandData (docId, null, r, null)
|
|
||||||
|
|
||||||
|
|
||||||
/// All data manipulations within myPrayerJournal
|
/// All data manipulations within myPrayerJournal
|
||||||
module Data =
|
module Data =
|
||||||
|
|
||||||
|
open FSharp.Control.Tasks.V2.ContextInsensitive
|
||||||
open Indexes
|
open Indexes
|
||||||
|
open Microsoft.FSharpLu
|
||||||
|
open Raven.Client.Documents
|
||||||
|
open Raven.Client.Documents.Linq
|
||||||
open Raven.Client.Documents.Session
|
open Raven.Client.Documents.Session
|
||||||
|
|
||||||
/// Add a history entry
|
/// Add a history entry
|
||||||
@ -134,11 +105,15 @@ module Data =
|
|||||||
|
|
||||||
/// Retrieve all answered requests for the given user
|
/// Retrieve all answered requests for the given user
|
||||||
let answeredRequests userId (sess : IAsyncDocumentSession) =
|
let answeredRequests userId (sess : IAsyncDocumentSession) =
|
||||||
sess.Query<JournalRequest, Requests_AsJournal>()
|
task {
|
||||||
.Where(fun r -> r.userId = userId && r.lastStatus = "Answered")
|
let! reqs =
|
||||||
.OrderByDescending(fun r -> r.asOf)
|
sess.Query<JournalRequest, Requests_AsJournal>()
|
||||||
.ProjectInto<JournalRequest>()
|
.Where(fun r -> r.userId = userId && r.lastStatus = "Answered")
|
||||||
.ToListAsync()
|
.OrderByDescending(fun r -> r.asOf)
|
||||||
|
.ProjectInto<JournalRequest>()
|
||||||
|
.ToListAsync ()
|
||||||
|
return List.ofSeq reqs
|
||||||
|
}
|
||||||
|
|
||||||
/// Retrieve the user's current journal
|
/// Retrieve the user's current journal
|
||||||
let journalByUserId userId (sess : IAsyncDocumentSession) =
|
let journalByUserId userId (sess : IAsyncDocumentSession) =
|
||||||
|
@ -43,21 +43,13 @@ type Recurrence =
|
|||||||
| Days
|
| Days
|
||||||
| Weeks
|
| Weeks
|
||||||
module Recurrence =
|
module Recurrence =
|
||||||
/// The string reprsentation used in the database and the web app
|
|
||||||
// TODO/FIXME: will this be true in v2? it's not in the database...
|
|
||||||
let toString x =
|
|
||||||
match x with
|
|
||||||
| Immediate -> "immediate"
|
|
||||||
| Hours -> "hours"
|
|
||||||
| Days -> "days"
|
|
||||||
| Weeks -> "weeks"
|
|
||||||
/// Create a recurrence value from a string
|
/// Create a recurrence value from a string
|
||||||
let fromString x =
|
let fromString x =
|
||||||
match x with
|
match x with
|
||||||
| "immediate" -> Immediate
|
| "Immediate" -> Immediate
|
||||||
| "hours" -> Hours
|
| "Hours" -> Hours
|
||||||
| "days" -> Days
|
| "Days" -> Days
|
||||||
| "weeks" -> Weeks
|
| "Weeks" -> Weeks
|
||||||
| _ -> invalidOp (sprintf "%s is not a valid recurrence" x)
|
| _ -> invalidOp (sprintf "%s is not a valid recurrence" x)
|
||||||
/// The duration of the recurrence
|
/// The duration of the recurrence
|
||||||
let duration x =
|
let duration x =
|
||||||
@ -159,8 +151,8 @@ with
|
|||||||
// RavenDB doesn't like the "@"-suffixed properties from record types in a ProjectInto clause
|
// RavenDB doesn't like the "@"-suffixed properties from record types in a ProjectInto clause
|
||||||
[<NoComparison; NoEquality>]
|
[<NoComparison; NoEquality>]
|
||||||
type JournalRequest () =
|
type JournalRequest () =
|
||||||
/// The ID of the request
|
/// The ID of the request (just the CUID part)
|
||||||
[<DefaultValue>] val mutable requestId : RequestId
|
[<DefaultValue>] val mutable requestId : string
|
||||||
/// The ID of the user to whom the request belongs
|
/// The ID of the user to whom the request belongs
|
||||||
[<DefaultValue>] val mutable userId : UserId
|
[<DefaultValue>] val mutable userId : UserId
|
||||||
/// The current text of the request
|
/// The current text of the request
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/// HTTP handlers for the myPrayerJournal API
|
/// HTTP handlers for the myPrayerJournal API
|
||||||
[<RequireQualifiedAccess>]
|
[<RequireQualifiedAccess>]
|
||||||
module MyPrayerJournal.Api.Handlers
|
module MyPrayerJournal.Handlers
|
||||||
|
|
||||||
open FSharp.Control.Tasks.V2.ContextInsensitive
|
open FSharp.Control.Tasks.V2.ContextInsensitive
|
||||||
open Giraffe
|
open Giraffe
|
||||||
@ -46,7 +46,9 @@ module private Helpers =
|
|||||||
|
|
||||||
/// Create a RavenDB session
|
/// Create a RavenDB session
|
||||||
let session (ctx : HttpContext) =
|
let session (ctx : HttpContext) =
|
||||||
ctx.GetService<IDocumentStore>().OpenAsyncSession ()
|
let sess = ctx.GetService<IDocumentStore>().OpenAsyncSession ()
|
||||||
|
sess.Advanced.WaitForIndexesAfterSaveChanges ()
|
||||||
|
sess
|
||||||
|
|
||||||
/// Get the user's "sub" claim
|
/// Get the user's "sub" claim
|
||||||
let user (ctx : HttpContext) =
|
let user (ctx : HttpContext) =
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||||
<Version>1.2.2.0</Version>
|
<Version>2.0.0.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace MyPrayerJournal.Api
|
module MyPrayerJournal.Api
|
||||||
|
|
||||||
open Microsoft.AspNetCore.Builder
|
open Microsoft.AspNetCore.Builder
|
||||||
open Microsoft.AspNetCore.Hosting
|
open Microsoft.AspNetCore.Hosting
|
||||||
@ -40,10 +40,10 @@ module Configure =
|
|||||||
open Giraffe.TokenRouter
|
open Giraffe.TokenRouter
|
||||||
open Microsoft.AspNetCore.Authentication.JwtBearer
|
open Microsoft.AspNetCore.Authentication.JwtBearer
|
||||||
open Microsoft.Extensions.DependencyInjection
|
open Microsoft.Extensions.DependencyInjection
|
||||||
open Microsoft.FSharpLu.Json
|
|
||||||
open MyPrayerJournal
|
open MyPrayerJournal
|
||||||
open MyPrayerJournal.Indexes
|
open MyPrayerJournal.Indexes
|
||||||
open Newtonsoft.Json
|
open Newtonsoft.Json
|
||||||
|
open Newtonsoft.Json.Serialization
|
||||||
open Raven.Client.Documents
|
open Raven.Client.Documents
|
||||||
open Raven.Client.Documents.Indexes
|
open Raven.Client.Documents.Indexes
|
||||||
open System.Security.Cryptography.X509Certificates
|
open System.Security.Cryptography.X509Certificates
|
||||||
@ -51,19 +51,14 @@ module Configure =
|
|||||||
/// Configure dependency injection
|
/// Configure dependency injection
|
||||||
let services (bldr : IWebHostBuilder) =
|
let services (bldr : IWebHostBuilder) =
|
||||||
let svcs (sc : IServiceCollection) =
|
let svcs (sc : IServiceCollection) =
|
||||||
/// A set of JSON converters used for both Giraffe's request serialization and RavenDB's storage
|
|
||||||
let jsonConverters : JsonConverter seq =
|
|
||||||
seq {
|
|
||||||
yield! Converters.all
|
|
||||||
yield CompactUnionJsonConverter true
|
|
||||||
}
|
|
||||||
/// Custom settings for the JSON serializer (uses compact representation for options and DUs)
|
/// Custom settings for the JSON serializer (uses compact representation for options and DUs)
|
||||||
let jsonSettings =
|
let jsonSettings =
|
||||||
let x = NewtonsoftJsonSerializer.DefaultSettings
|
let x = NewtonsoftJsonSerializer.DefaultSettings
|
||||||
jsonConverters |> List.ofSeq |> List.iter x.Converters.Add
|
Converters.all |> List.ofSeq |> List.iter x.Converters.Add
|
||||||
x.NullValueHandling <- NullValueHandling.Ignore
|
x.NullValueHandling <- NullValueHandling.Ignore
|
||||||
x.MissingMemberHandling <- MissingMemberHandling.Error
|
x.MissingMemberHandling <- MissingMemberHandling.Error
|
||||||
x.Formatting <- Formatting.Indented
|
x.Formatting <- Formatting.Indented
|
||||||
|
x.ContractResolver <- DefaultContractResolver ()
|
||||||
x
|
x
|
||||||
|
|
||||||
use sp = sc.BuildServiceProvider ()
|
use sp = sc.BuildServiceProvider ()
|
||||||
@ -87,10 +82,12 @@ module Configure =
|
|||||||
let store = new DocumentStore ()
|
let store = new DocumentStore ()
|
||||||
store.Urls <- [| config.["URL"] |]
|
store.Urls <- [| config.["URL"] |]
|
||||||
store.Database <- config.["Database"]
|
store.Database <- config.["Database"]
|
||||||
// store.Certificate <- new X509Certificate2 (config.["Certificate"], config.["Password"])
|
match isNull config.["Certificate"] with
|
||||||
store.Conventions.CustomizeJsonSerializer <- fun x -> jsonConverters |> List.ofSeq |> List.iter x.Converters.Add
|
| true -> ()
|
||||||
|
| false -> store.Certificate <- new X509Certificate2 (config.["Certificate"], config.["Password"])
|
||||||
|
store.Conventions.CustomizeJsonSerializer <- fun x -> Converters.all |> List.ofSeq |> List.iter x.Converters.Add
|
||||||
store.Initialize () |> (sc.AddSingleton >> ignore)
|
store.Initialize () |> (sc.AddSingleton >> ignore)
|
||||||
IndexCreation.CreateIndexes (typeof<Requests_ByUserId>.Assembly, store)
|
IndexCreation.CreateIndexes (typeof<Requests_AsJournal>.Assembly, store)
|
||||||
bldr.ConfigureServices svcs
|
bldr.ConfigureServices svcs
|
||||||
|
|
||||||
open Microsoft.Extensions.Logging
|
open Microsoft.Extensions.Logging
|
||||||
@ -169,13 +166,11 @@ module Configure =
|
|||||||
/// Build the web host from the given configuration
|
/// Build the web host from the given configuration
|
||||||
let buildHost (bldr : IWebHostBuilder) = bldr.Build ()
|
let buildHost (bldr : IWebHostBuilder) = bldr.Build ()
|
||||||
|
|
||||||
module Program =
|
let exitCode = 0
|
||||||
|
|
||||||
let exitCode = 0
|
[<EntryPoint>]
|
||||||
|
let main _ =
|
||||||
[<EntryPoint>]
|
let appRoot = Directory.GetCurrentDirectory ()
|
||||||
let main _ =
|
use host = WebHostBuilder() |> (Configure.webHost appRoot [| "wwwroot" |] >> Configure.buildHost)
|
||||||
let appRoot = Directory.GetCurrentDirectory ()
|
host.Run ()
|
||||||
use host = WebHostBuilder() |> (Configure.webHost appRoot [| "wwwroot" |] >> Configure.buildHost)
|
exitCode
|
||||||
host.Run ()
|
|
||||||
exitCode
|
|
||||||
|
@ -39,7 +39,11 @@ export default {
|
|||||||
return this.$refs.toast
|
return this.$refs.toast
|
||||||
},
|
},
|
||||||
version () {
|
version () {
|
||||||
return version.endsWith('.0') ? version.substr(0, version.length - 2) : version
|
return version.endsWith('.0')
|
||||||
|
? version.endsWith('.0.0')
|
||||||
|
? version.substr(0, version.length - 4)
|
||||||
|
: version.substr(0, version.length - 2)
|
||||||
|
: version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ article.mpj-main-content-wide(role='main')
|
|||||||
br
|
br
|
||||||
.mpj-journal(v-if='journal.length > 0')
|
.mpj-journal(v-if='journal.length > 0')
|
||||||
request-card(v-for='request in journal'
|
request-card(v-for='request in journal'
|
||||||
:key='request.Id'
|
:key='request.requestId'
|
||||||
:request='request'
|
:request='request'
|
||||||
:events='eventBus'
|
:events='eventBus'
|
||||||
:toast='toast')
|
:toast='toast')
|
||||||
|
@ -5,7 +5,7 @@ article.mpj-main-content(role='main')
|
|||||||
p.mpj-text-center(v-if='requests.length === 0'): em.
|
p.mpj-text-center(v-if='requests.length === 0'): em.
|
||||||
No active requests found; return to #[router-link(:to='{ name: "Journal" } ') your journal]
|
No active requests found; return to #[router-link(:to='{ name: "Journal" } ') your journal]
|
||||||
request-list-item(v-for='req in requests'
|
request-list-item(v-for='req in requests'
|
||||||
:key='req.Id'
|
:key='req.requestId'
|
||||||
:request='req'
|
:request='req'
|
||||||
:toast='toast')
|
:toast='toast')
|
||||||
p(v-else) Loading journal...
|
p(v-else) Loading journal...
|
||||||
|
@ -5,7 +5,7 @@ article.mpj-main-content(role='main')
|
|||||||
p.text-center(v-if='requests.length === 0'): em.
|
p.text-center(v-if='requests.length === 0'): em.
|
||||||
No answered requests found; once you have marked one as “Answered”, it will appear here
|
No answered requests found; once you have marked one as “Answered”, it will appear here
|
||||||
request-list-item(v-for='req in requests'
|
request-list-item(v-for='req in requests'
|
||||||
:key='req.Id'
|
:key='req.requestId'
|
||||||
:request='req'
|
:request='req'
|
||||||
:toast='toast')
|
:toast='toast')
|
||||||
p(v-else) Loading answered requests...
|
p(v-else) Loading answered requests...
|
||||||
|
@ -42,7 +42,7 @@ article.mpj-main-content(role='main')
|
|||||||
input(v-model='form.recur.typ'
|
input(v-model='form.recur.typ'
|
||||||
type='radio'
|
type='radio'
|
||||||
name='recur'
|
name='recur'
|
||||||
value='immediate')
|
value='Immediate')
|
||||||
| Immediately
|
| Immediately
|
||||||
|
|
|
|
||||||
label.normal
|
label.normal
|
||||||
@ -56,9 +56,9 @@ article.mpj-main-content(role='main')
|
|||||||
:disabled='!showRecurrence').mpj-recur-count
|
:disabled='!showRecurrence').mpj-recur-count
|
||||||
select(v-model='form.recur.other'
|
select(v-model='form.recur.other'
|
||||||
:disabled='!showRecurrence').mpj-recur-type
|
:disabled='!showRecurrence').mpj-recur-type
|
||||||
option(value='hours') hours
|
option(value='Hours') hours
|
||||||
option(value='days') days
|
option(value='Days') days
|
||||||
option(value='weeks') weeks
|
option(value='Weeks') weeks
|
||||||
.mpj-text-right
|
.mpj-text-right
|
||||||
button(:disabled='!isValidRecurrence'
|
button(:disabled='!isValidRecurrence'
|
||||||
@click.stop='saveRequest()').primary.
|
@click.stop='saveRequest()').primary.
|
||||||
@ -92,7 +92,7 @@ export default {
|
|||||||
requestText: '',
|
requestText: '',
|
||||||
status: 'Updated',
|
status: 'Updated',
|
||||||
recur: {
|
recur: {
|
||||||
typ: 'immediate',
|
typ: 'Immediate',
|
||||||
other: '',
|
other: '',
|
||||||
count: ''
|
count: ''
|
||||||
}
|
}
|
||||||
@ -101,16 +101,16 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isValidRecurrence () {
|
isValidRecurrence () {
|
||||||
if (this.form.recur.typ === 'immediate') return true
|
if (this.form.recur.typ === 'Immediate') return true
|
||||||
const count = Number.parseInt(this.form.recur.count)
|
const count = Number.parseInt(this.form.recur.count)
|
||||||
if (isNaN(count) || this.form.recur.other === '') return false
|
if (isNaN(count) || this.form.recur.other === '') return false
|
||||||
if (this.form.recur.other === 'hours' && count > (365 * 24)) return false
|
if (this.form.recur.other === 'Hours' && count > (365 * 24)) return false
|
||||||
if (this.form.recur.other === 'days' && count > 365) return false
|
if (this.form.recur.other === 'Days' && count > 365) return false
|
||||||
if (this.form.recur.other === 'weeks' && count > 52) return false
|
if (this.form.recur.other === 'Weeks' && count > 52) return false
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
showRecurrence () {
|
showRecurrence () {
|
||||||
return this.form.recur.typ !== 'immediate'
|
return this.form.recur.typ !== 'Immediate'
|
||||||
},
|
},
|
||||||
toast () {
|
toast () {
|
||||||
return this.$parent.$refs.toast
|
return this.$parent.$refs.toast
|
||||||
@ -125,7 +125,7 @@ export default {
|
|||||||
this.form.requestId = ''
|
this.form.requestId = ''
|
||||||
this.form.requestText = ''
|
this.form.requestText = ''
|
||||||
this.form.status = 'Created'
|
this.form.status = 'Created'
|
||||||
this.form.recur.typ = 'immediate'
|
this.form.recur.typ = 'Immediate'
|
||||||
this.form.recur.other = ''
|
this.form.recur.other = ''
|
||||||
this.form.recur.count = ''
|
this.form.recur.count = ''
|
||||||
} else {
|
} else {
|
||||||
@ -134,12 +134,12 @@ export default {
|
|||||||
if (this.journal.length === 0) {
|
if (this.journal.length === 0) {
|
||||||
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
||||||
}
|
}
|
||||||
const req = this.journal.filter(r => r.Id === this.id)[0]
|
const req = this.journal.filter(r => r.requestId === this.id)[0]
|
||||||
this.form.requestId = this.id
|
this.form.requestId = this.id
|
||||||
this.form.requestText = req.text
|
this.form.requestText = req.text
|
||||||
this.form.status = 'Updated'
|
this.form.status = 'Updated'
|
||||||
if (req.recurType === 'immediate') {
|
if (req.recurType === 'Immediate') {
|
||||||
this.form.recur.typ = 'immediate'
|
this.form.recur.typ = 'Immediate'
|
||||||
this.form.recur.other = ''
|
this.form.recur.other = ''
|
||||||
this.form.recur.count = ''
|
this.form.recur.count = ''
|
||||||
} else {
|
} else {
|
||||||
@ -166,8 +166,8 @@ export default {
|
|||||||
await this.$store.dispatch(actions.ADD_REQUEST, {
|
await this.$store.dispatch(actions.ADD_REQUEST, {
|
||||||
progress: this.$Progress,
|
progress: this.$Progress,
|
||||||
requestText: this.form.requestText,
|
requestText: this.form.requestText,
|
||||||
recurType: this.form.recur.typ === 'immediate' ? 'immediate' : this.form.recur.other,
|
recurType: this.form.recur.typ === 'Immediate' ? 'Immediate' : this.form.recur.other,
|
||||||
recurCount: this.form.recur.typ === 'immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
recurCount: this.form.recur.typ === 'Immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
||||||
})
|
})
|
||||||
this.toast.showToast('New prayer request added', { theme: 'success' })
|
this.toast.showToast('New prayer request added', { theme: 'success' })
|
||||||
} else {
|
} else {
|
||||||
@ -176,8 +176,8 @@ export default {
|
|||||||
requestId: this.form.requestId,
|
requestId: this.form.requestId,
|
||||||
updateText: this.form.requestText,
|
updateText: this.form.requestText,
|
||||||
status: this.form.status,
|
status: this.form.status,
|
||||||
recurType: this.form.recur.typ === 'immediate' ? 'immediate' : this.form.recur.other,
|
recurType: this.form.recur.typ === 'Immediate' ? 'Immediate' : this.form.recur.other,
|
||||||
recurCount: this.form.recur.typ === 'immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
recurCount: this.form.recur.typ === 'Immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
||||||
})
|
})
|
||||||
if (this.form.status === 'Answered') {
|
if (this.form.status === 'Answered') {
|
||||||
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
|
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
|
||||||
|
@ -85,7 +85,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
openDialog (request) {
|
openDialog (request) {
|
||||||
this.form.requestId = request.Id
|
this.form.requestId = request.requestId
|
||||||
this.notesVisible = true
|
this.notesVisible = true
|
||||||
},
|
},
|
||||||
async saveNotes () {
|
async saveNotes () {
|
||||||
|
@ -36,20 +36,20 @@ export default {
|
|||||||
async markPrayed () {
|
async markPrayed () {
|
||||||
await this.$store.dispatch(actions.UPDATE_REQUEST, {
|
await this.$store.dispatch(actions.UPDATE_REQUEST, {
|
||||||
progress: this.$Progress,
|
progress: this.$Progress,
|
||||||
requestId: this.request.Id,
|
requestId: this.request.requestId,
|
||||||
status: 'Prayed',
|
status: 'Prayed',
|
||||||
updateText: ''
|
updateText: ''
|
||||||
})
|
})
|
||||||
this.toast.showToast('Request marked as prayed', { theme: 'success' })
|
this.toast.showToast('Request marked as prayed', { theme: 'success' })
|
||||||
},
|
},
|
||||||
showEdit () {
|
showEdit () {
|
||||||
this.$router.push({ name: 'EditRequest', params: { id: this.request.Id } })
|
this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
|
||||||
},
|
},
|
||||||
showNotes () {
|
showNotes () {
|
||||||
this.events.$emit('notes', this.request)
|
this.events.$emit('notes', this.request)
|
||||||
},
|
},
|
||||||
snooze () {
|
snooze () {
|
||||||
this.events.$emit('snooze', this.request.Id)
|
this.events.$emit('snooze', this.request.requestId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,26 +60,26 @@ export default {
|
|||||||
async cancelSnooze () {
|
async cancelSnooze () {
|
||||||
await this.$store.dispatch(actions.SNOOZE_REQUEST, {
|
await this.$store.dispatch(actions.SNOOZE_REQUEST, {
|
||||||
progress: this.$Progress,
|
progress: this.$Progress,
|
||||||
requestId: this.request.Id,
|
requestId: this.request.requestId,
|
||||||
until: 0
|
until: 0
|
||||||
})
|
})
|
||||||
this.toast.showToast('Request un-snoozed', { theme: 'success' })
|
this.toast.showToast('Request un-snoozed', { theme: 'success' })
|
||||||
this.$parent.$emit('requestUnsnoozed')
|
this.$parent.$emit('requestUnsnoozed')
|
||||||
},
|
},
|
||||||
editRequest () {
|
editRequest () {
|
||||||
this.$router.push({ name: 'EditRequest', params: { id: this.request.Id } })
|
this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
|
||||||
},
|
},
|
||||||
async showNow () {
|
async showNow () {
|
||||||
await this.$store.dispatch(actions.SHOW_REQUEST_NOW, {
|
await this.$store.dispatch(actions.SHOW_REQUEST_NOW, {
|
||||||
progress: this.$Progress,
|
progress: this.$Progress,
|
||||||
requestId: this.request.Id,
|
requestId: this.request.requestId,
|
||||||
showAfter: Date.now()
|
showAfter: Date.now()
|
||||||
})
|
})
|
||||||
this.toast.showToast('Recurrence skipped; request now shows in journal', { theme: 'success' })
|
this.toast.showToast('Recurrence skipped; request now shows in journal', { theme: 'success' })
|
||||||
this.$parent.$emit('requestNowShown')
|
this.$parent.$emit('requestNowShown')
|
||||||
},
|
},
|
||||||
viewFull () {
|
viewFull () {
|
||||||
this.$router.push({ name: 'FullRequest', params: { id: this.request.Id } })
|
this.$router.push({ name: 'FullRequest', params: { id: this.request.requestId } })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ article.mpj-main-content(role='main')
|
|||||||
p.mpj-text-center(v-if='requests.length === 0'): em.
|
p.mpj-text-center(v-if='requests.length === 0'): em.
|
||||||
No snoozed requests found; return to #[router-link(:to='{ name: "Journal" } ') your journal]
|
No snoozed requests found; return to #[router-link(:to='{ name: "Journal" } ') your journal]
|
||||||
request-list-item(v-for='req in requests'
|
request-list-item(v-for='req in requests'
|
||||||
:key='req.Id'
|
:key='req.requestId'
|
||||||
:request='req'
|
:request='req'
|
||||||
:toast='toast')
|
:toast='toast')
|
||||||
p(v-else) Loading journal...
|
p(v-else) Loading journal...
|
||||||
|
@ -56,7 +56,7 @@ export default new Vuex.Store({
|
|||||||
state.journal.push(newRequest)
|
state.journal.push(newRequest)
|
||||||
},
|
},
|
||||||
[mutations.REQUEST_UPDATED] (state, request) {
|
[mutations.REQUEST_UPDATED] (state, request) {
|
||||||
let jrnl = state.journal.filter(it => it.Id !== request.Id)
|
let jrnl = state.journal.filter(it => it.requestId !== request.requestId)
|
||||||
if (request.lastStatus !== 'Answered') jrnl.push(request)
|
if (request.lastStatus !== 'Answered') jrnl.push(request)
|
||||||
state.journal = jrnl
|
state.journal = jrnl
|
||||||
},
|
},
|
||||||
@ -103,7 +103,7 @@ export default new Vuex.Store({
|
|||||||
async [actions.UPDATE_REQUEST] ({ commit, state }, { progress, requestId, status, updateText, recurType, recurCount }) {
|
async [actions.UPDATE_REQUEST] ({ commit, state }, { progress, requestId, status, updateText, recurType, recurCount }) {
|
||||||
progress.start()
|
progress.start()
|
||||||
try {
|
try {
|
||||||
let oldReq = (state.journal.filter(req => req.Id === requestId) || [])[0] || {}
|
let oldReq = (state.journal.filter(req => req.requestId === requestId) || [])[0] || {}
|
||||||
if (!(status === 'Prayed' && updateText === '')) {
|
if (!(status === 'Prayed' && updateText === '')) {
|
||||||
if (status !== 'Answered' && (oldReq.recurType !== recurType || oldReq.recurCount !== recurCount)) {
|
if (status !== 'Answered' && (oldReq.recurType !== recurType || oldReq.recurCount !== recurCount)) {
|
||||||
await api.updateRecurrence(requestId, recurType, recurCount)
|
await api.updateRecurrence(requestId, recurType, recurCount)
|
||||||
|
Loading…
Reference in New Issue
Block a user