Merge branch 'master' into vue-cli-3
bringing in the changes for v0.9.8
This commit is contained in:
commit
3d0a00e08f
|
@ -16,15 +16,19 @@ myPrayerJournal uses login services using Google or Microsoft accounts. The only
|
||||||
|
|
||||||
## Your Prayer Journal
|
## Your Prayer Journal
|
||||||
|
|
||||||
Your current requests will be presented in three columns (or two or one, depending on the size of your screen or device). Each request is in its own card, and the buttons at the top of each card apply to that request. The last line of each request also tells you how long it has been since anything has been done on that request. Any time you see something like "a few minutes ago," you can hover over that to see the actual date/time the action was taken.
|
Your current requests will be presented in columns (usually three, but it could be more or less, depending on the size of your screen or device). Each request is in its own card, and the buttons at the top of each card apply to that request. The last line of each request also tells you how long it has been since anything has been done on that request. Any time you see something like "a few minutes ago," you can hover over that to see the actual date/time the action was taken.
|
||||||
|
|
||||||
## Adding a Request
|
## Adding a Request
|
||||||
|
|
||||||
To add a request, click the "Add a New Request" button at the top of your journal. Then, enter the text of the request as you see fit; there is no right or wrong way, and you are the only person who will see the text you enter. When you save the request, it will go to the bottom of the list of requests.
|
To add a request, click the "Add a New Request" button at the top of your journal. Then, enter the text of the request as you see fit; there is no right or wrong way, and you are the only person who will see the text you enter. When you save the request, it will go to the bottom of the list of requests.
|
||||||
|
|
||||||
|
## Setting Request Recurrence
|
||||||
|
|
||||||
|
When you add or update a request, you can choose whether requests go to the bottom of the journal once they have been marked "Prayed" or whether they will reappear after a delay. You can set recurrence in terms of hours, days, or weeks, but it cannot be longer than 365 days. If you decide you want a request to reappear sooner, you can skip the current delay; click the "Active" menu link, find the request in the list (likely near the bottom), and click the "Show Now" button.
|
||||||
|
|
||||||
## Praying for Requests
|
## Praying for Requests
|
||||||
|
|
||||||
The first button for each request has a checkmark icon; clicking this button will mark the request as "Prayed" and move it to the bottom of the list. This allows you, if you're praying through your requests, to start at the top left (with the request that it's been the longest since you've prayed) and click the button as you pray; when the request goes to the bottom of the list, the next-least-recently-prayed request will take the top spot.
|
The first button for each request has a checkmark icon; clicking this button will mark the request as "Prayed" and move it to the bottom of the list (or off, if you've set a recurrence period for the request). This allows you, if you're praying through your requests, to start at the top left (with the request that it's been the longest since you've prayed) and click the button as you pray; when the request move below or away, the next-least-recently-prayed request will take the top spot.
|
||||||
|
|
||||||
## Editing Requests
|
## Editing Requests
|
||||||
|
|
||||||
|
@ -32,22 +36,20 @@ The second button for each request has a pencil icon. This allows you to edit th
|
||||||
|
|
||||||
## Adding Notes
|
## Adding Notes
|
||||||
|
|
||||||
The third button for each request has an icon that looks like a piece of paper with writing; this lets you record notes about the request. If there is something you want to record that doesn't change the text of the request, this is the place to do it. For example, you may be praying for a long-term health issue, and that person tells you that their status is the same; or, you may want to record something God said to you while you were praying for that request.
|
The third button for each request has an icon that looks like a speech bubble with lines on it; this lets you record notes about the request. If there is something you want to record that doesn't change the text of the request, this is the place to do it. For example, you may be praying for a long-term health issue, and that person tells you that their status is the same; or, you may want to record something God said to you while you were praying for that request.
|
||||||
|
|
||||||
## Viewing a Request and Its History
|
|
||||||
|
|
||||||
myPrayerJournal tracks all of the actions related to a request; the fourth button, with the magnifying glass icon, will show you the entire history, including the text as it changed, and all the times "Prayed" was recorded.
|
|
||||||
|
|
||||||
## Snoozing Requests
|
## Snoozing Requests
|
||||||
|
|
||||||
There may be a time where a request does not need to appear. The fifth button, with the clock icon, allows you to snooze requests until the day you specify. Additionally, if you have any snoozed requests, a "Snoozed" menu item will appear next to the "Journal" one; this page allows you to see what requests are snoozed, and return them to your journal by canceling the snooze.
|
There may be a time where a request does not need to appear. The fourth button, with the clock icon, allows you to snooze requests until the day you specify. Additionally, if you have any snoozed requests, a "Snoozed" menu item will appear next to the "Journal" one; this page allows you to see what requests are snoozed, and return them to your journal by canceling the snooze.
|
||||||
|
|
||||||
## Answered Requests
|
## Viewing a Request and Its History
|
||||||
|
|
||||||
Next to "Journal" on the top navigation is the word "Answered." This page lists all answered requests, from most recent to least recent, along with the text of the request at the time it was marked as answered. It will also show you when it was marked answered. The button at the bottom of each request, with the magnifying glass and the words "Show Full Request", link to a page that shows that request's complete history and notes, along with a few statistics about that request. The history and notes are listed from most recent to least recent; if you want to read it chronologically, just press the "End" key on your keyboard and read it from the bottom up.
|
myPrayerJournal tracks all of the actions related to a request; from the "Active" and "Answered" menu links (and "Snoozed", if it's showing), there is a "View Full Request" button. That page will show the current text of the request; how many times it has been marked as prayed; how long it has been an active request; and a log of all updates, prayers, and notes you have recorded. That log is listed from most recent to least recent; if you want to read it chronologically, just press the "End" key on your keyboard and read it from the bottom up.
|
||||||
|
|
||||||
|
The "Active" link will show all requests that have not yet been marked answered, including snoozed and recurring requests. If requests are snoozed, or in a recurrence period off the journal, there will be a button where you can return the request to the list (either "Cancel Snooze" or "Show Now"). The "Answered" link shows all requests that have been marked answered. The "Snoozed" link just shows snoozed requests.
|
||||||
|
|
||||||
## Final Notes
|
## Final Notes
|
||||||
|
|
||||||
- myPrayerJournal is currently in public beta. If you encounter errors, please [file an issue on GitHub](https://github.com/bit-badger/myPrayerJournal/issues) with as much detail as possible. You can also browse the list of issues to see what has been done and what is still left to do.
|
- myPrayerJournal is nearing the end of its public beta, approaching its first official release. If you encounter errors, please [file an issue on GitHub](https://github.com/bit-badger/myPrayerJournal/issues) with as much detail as possible. You can also browse the list of issues to see what has been done and what is still left to do.
|
||||||
- Prayer requests and their history are securely backed up nightly along with other Bit Badger Solutions data.
|
- Prayer requests and their history are securely backed up nightly along with other Bit Badger Solutions data.
|
||||||
- Prayer changes things - most of all, the one doing the praying. I pray that this tool enables you to deepen and strengthen your prayer life.
|
- Prayer changes things - most of all, the one doing the praying. I pray that this tool enables you to deepen and strengthen your prayer life.
|
||||||
|
|
|
@ -88,7 +88,7 @@ module Entities =
|
||||||
m.Property(fun e -> e.notes).IsRequired () |> ignore)
|
m.Property(fun e -> e.notes).IsRequired () |> ignore)
|
||||||
|> ignore
|
|> ignore
|
||||||
|
|
||||||
// Request is the identifying record for a prayer request.
|
/// Request is the identifying record for a prayer request
|
||||||
and [<CLIMutable; NoComparison; NoEquality>] Request =
|
and [<CLIMutable; NoComparison; NoEquality>] Request =
|
||||||
{ /// The ID of the request
|
{ /// The ID of the request
|
||||||
requestId : RequestId
|
requestId : RequestId
|
||||||
|
@ -96,8 +96,14 @@ module Entities =
|
||||||
enteredOn : int64
|
enteredOn : int64
|
||||||
/// The ID of the user to whom this request belongs ("sub" from the JWT)
|
/// The ID of the user to whom this request belongs ("sub" from the JWT)
|
||||||
userId : string
|
userId : string
|
||||||
/// The time that this request should reappear in the user's journal
|
/// The time at which this request should reappear in the user's journal by manual user choice
|
||||||
snoozedUntil : int64
|
snoozedUntil : int64
|
||||||
|
/// The time at which this request should reappear in the user's journal by recurrence
|
||||||
|
showAfter : int64
|
||||||
|
/// The type of recurrence for this request
|
||||||
|
recurType : string
|
||||||
|
/// How many of the recurrence intervals should occur between appearances in the journal
|
||||||
|
recurCount : int16
|
||||||
/// The history entries for this request
|
/// The history entries for this request
|
||||||
history : ICollection<History>
|
history : ICollection<History>
|
||||||
/// The notes for this request
|
/// The notes for this request
|
||||||
|
@ -110,6 +116,9 @@ module Entities =
|
||||||
enteredOn = 0L
|
enteredOn = 0L
|
||||||
userId = ""
|
userId = ""
|
||||||
snoozedUntil = 0L
|
snoozedUntil = 0L
|
||||||
|
showAfter = 0L
|
||||||
|
recurType = "immediate"
|
||||||
|
recurCount = 0s
|
||||||
history = List<History> ()
|
history = List<History> ()
|
||||||
notes = List<Note> ()
|
notes = List<Note> ()
|
||||||
}
|
}
|
||||||
|
@ -123,6 +132,9 @@ module Entities =
|
||||||
m.Property(fun e -> e.enteredOn).IsRequired () |> ignore
|
m.Property(fun e -> e.enteredOn).IsRequired () |> ignore
|
||||||
m.Property(fun e -> e.userId).IsRequired () |> ignore
|
m.Property(fun e -> e.userId).IsRequired () |> ignore
|
||||||
m.Property(fun e -> e.snoozedUntil).IsRequired () |> ignore
|
m.Property(fun e -> e.snoozedUntil).IsRequired () |> ignore
|
||||||
|
m.Property(fun e -> e.showAfter).IsRequired () |> ignore
|
||||||
|
m.Property(fun e -> e.recurType).IsRequired() |> ignore
|
||||||
|
m.Property(fun e -> e.recurCount).IsRequired() |> ignore
|
||||||
m.HasMany(fun e -> e.history :> IEnumerable<History>)
|
m.HasMany(fun e -> e.history :> IEnumerable<History>)
|
||||||
.WithOne()
|
.WithOne()
|
||||||
.HasForeignKey(fun e -> e.requestId :> obj)
|
.HasForeignKey(fun e -> e.requestId :> obj)
|
||||||
|
@ -149,6 +161,12 @@ module Entities =
|
||||||
lastStatus : string
|
lastStatus : string
|
||||||
/// The time that this request should reappear in the user's journal
|
/// The time that this request should reappear in the user's journal
|
||||||
snoozedUntil : int64
|
snoozedUntil : int64
|
||||||
|
/// The time after which this request should reappear in the user's journal by configured recurrence
|
||||||
|
showAfter : int64
|
||||||
|
/// The type of recurrence for this request
|
||||||
|
recurType : string
|
||||||
|
/// How many of the recurrence intervals should occur between appearances in the journal
|
||||||
|
recurCount : int16
|
||||||
/// History entries for the request
|
/// History entries for the request
|
||||||
history : History list
|
history : History list
|
||||||
/// Note entries for the request
|
/// Note entries for the request
|
||||||
|
@ -227,7 +245,7 @@ type AppDbContext (opts : DbContextOptions<AppDbContext>) =
|
||||||
.OrderBy(fun r -> r.asOf)
|
.OrderBy(fun r -> r.asOf)
|
||||||
|
|
||||||
/// Retrieve a request by its ID and user ID
|
/// Retrieve a request by its ID and user ID
|
||||||
member this.TryRequestById reqId userId : Task<Request option> =
|
member this.TryRequestById reqId userId =
|
||||||
task {
|
task {
|
||||||
let! req = this.Requests.AsNoTracking().FirstOrDefaultAsync(fun r -> r.requestId = reqId && r.userId = userId)
|
let! req = this.Requests.AsNoTracking().FirstOrDefaultAsync(fun r -> r.requestId = reqId && r.userId = userId)
|
||||||
return toOption req
|
return toOption req
|
||||||
|
@ -236,8 +254,7 @@ type AppDbContext (opts : DbContextOptions<AppDbContext>) =
|
||||||
/// Retrieve notes for a request by its ID and user ID
|
/// Retrieve notes for a request by its ID and user ID
|
||||||
member this.NotesById reqId userId =
|
member this.NotesById reqId userId =
|
||||||
task {
|
task {
|
||||||
let! req = this.TryRequestById reqId userId
|
match! this.TryRequestById reqId userId with
|
||||||
match req with
|
|
||||||
| Some _ -> return this.Notes.AsNoTracking().Where(fun n -> n.requestId = reqId) |> List.ofSeq
|
| Some _ -> return this.Notes.AsNoTracking().Where(fun n -> n.requestId = reqId) |> List.ofSeq
|
||||||
| None -> return []
|
| None -> return []
|
||||||
}
|
}
|
||||||
|
@ -250,34 +267,17 @@ type AppDbContext (opts : DbContextOptions<AppDbContext>) =
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
member this.TryCompleteRequestById requestId userId =
|
member this.TryFullRequestById requestId userId =
|
||||||
task {
|
task {
|
||||||
let! req = this.TryJournalById requestId userId
|
match! this.TryJournalById requestId userId with
|
||||||
match req with
|
| Some req ->
|
||||||
| Some r ->
|
|
||||||
let! fullReq =
|
let! fullReq =
|
||||||
this.Requests.AsNoTracking()
|
this.Requests.AsNoTracking()
|
||||||
.Include(fun r -> r.history)
|
.Include(fun r -> r.history)
|
||||||
.Include(fun r -> r.notes)
|
.Include(fun r -> r.notes)
|
||||||
.FirstOrDefaultAsync(fun r -> r.requestId = requestId && r.userId = userId)
|
.FirstOrDefaultAsync(fun r -> r.requestId = requestId && r.userId = userId)
|
||||||
match toOption fullReq with
|
match toOption fullReq with
|
||||||
| Some _ -> return Some { r with history = List.ofSeq fullReq.history; notes = List.ofSeq fullReq.notes }
|
| Some _ -> return Some { req with history = List.ofSeq fullReq.history; notes = List.ofSeq fullReq.notes }
|
||||||
| None -> return None
|
|
||||||
| None -> return None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve a request, including its history, by its ID and user ID
|
|
||||||
member this.TryFullRequestById requestId userId =
|
|
||||||
task {
|
|
||||||
let! req = this.TryJournalById requestId userId
|
|
||||||
match req with
|
|
||||||
| Some r ->
|
|
||||||
let! fullReq =
|
|
||||||
this.Requests.AsNoTracking()
|
|
||||||
.Include(fun r -> r.history)
|
|
||||||
.FirstOrDefaultAsync(fun r -> r.requestId = requestId && r.userId = userId)
|
|
||||||
match toOption fullReq with
|
|
||||||
| Some _ -> return Some { r with history = List.ofSeq fullReq.history }
|
|
||||||
| None -> return None
|
| None -> return None
|
||||||
| None -> return None
|
| None -> return None
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,14 @@ open Giraffe
|
||||||
open MyPrayerJournal
|
open MyPrayerJournal
|
||||||
open System
|
open System
|
||||||
|
|
||||||
|
/// Handler to return Vue files
|
||||||
|
module Vue =
|
||||||
|
|
||||||
|
/// The application index page
|
||||||
|
let app : HttpHandler = htmlFile "wwwroot/index.html"
|
||||||
|
|
||||||
|
|
||||||
|
/// Handlers for error conditions
|
||||||
module Error =
|
module Error =
|
||||||
|
|
||||||
open Microsoft.Extensions.Logging
|
open Microsoft.Extensions.Logging
|
||||||
|
@ -18,12 +26,12 @@ module Error =
|
||||||
/// Handle 404s from the API, sending known URL paths to the Vue app so that they can be handled there
|
/// Handle 404s from the API, sending known URL paths to the Vue app so that they can be handled there
|
||||||
let notFound : HttpHandler =
|
let notFound : HttpHandler =
|
||||||
fun next ctx ->
|
fun next ctx ->
|
||||||
[ "/answered"; "/journal"; "/snoozed"; "/user" ]
|
[ "/journal"; "/legal"; "/request"; "/user" ]
|
||||||
|> List.filter ctx.Request.Path.Value.StartsWith
|
|> List.filter ctx.Request.Path.Value.StartsWith
|
||||||
|> List.length
|
|> List.length
|
||||||
|> function
|
|> function
|
||||||
| 0 -> (setStatusCode 404 >=> json ([ "error", "not found" ] |> dict)) next ctx
|
| 0 -> (setStatusCode 404 >=> json ([ "error", "not found" ] |> dict)) next ctx
|
||||||
| _ -> htmlFile "wwwroot/index.html" next ctx
|
| _ -> Vue.app next ctx
|
||||||
|
|
||||||
|
|
||||||
/// Handler helpers
|
/// Handler helpers
|
||||||
|
@ -87,13 +95,33 @@ module Models =
|
||||||
notes : string
|
notes : string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recurrence update
|
||||||
|
[<CLIMutable>]
|
||||||
|
type Recurrence =
|
||||||
|
{ /// The recurrence type
|
||||||
|
recurType : string
|
||||||
|
/// The recurrence cound
|
||||||
|
recurCount : int16
|
||||||
|
}
|
||||||
|
|
||||||
/// A prayer request
|
/// A prayer request
|
||||||
[<CLIMutable>]
|
[<CLIMutable>]
|
||||||
type Request =
|
type Request =
|
||||||
{ /// The text of the request
|
{ /// The text of the request
|
||||||
requestText : string
|
requestText : string
|
||||||
|
/// The recurrence type
|
||||||
|
recurType : string
|
||||||
|
/// The recurrence count
|
||||||
|
recurCount : int16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset the "showAfter" property on a request
|
||||||
|
[<CLIMutable>]
|
||||||
|
type Show =
|
||||||
|
{ /// The time after which the request should appear
|
||||||
|
showAfter : int64
|
||||||
|
}
|
||||||
|
|
||||||
/// The time until which a request should not appear in the journal
|
/// The time until which a request should not appear in the journal
|
||||||
[<CLIMutable>]
|
[<CLIMutable>]
|
||||||
type SnoozeUntil =
|
type SnoozeUntil =
|
||||||
|
@ -119,6 +147,15 @@ module Request =
|
||||||
|
|
||||||
open NCuid
|
open NCuid
|
||||||
|
|
||||||
|
/// Ticks per recurrence
|
||||||
|
let private recurrence =
|
||||||
|
[ "immediate", 0L
|
||||||
|
"hours", 3600000L
|
||||||
|
"days", 86400000L
|
||||||
|
"weeks", 604800000L
|
||||||
|
]
|
||||||
|
|> Map.ofList
|
||||||
|
|
||||||
/// POST /api/request
|
/// POST /api/request
|
||||||
let add : HttpHandler =
|
let add : HttpHandler =
|
||||||
authorize
|
authorize
|
||||||
|
@ -130,10 +167,12 @@ module Request =
|
||||||
let usrId = userId ctx
|
let usrId = userId ctx
|
||||||
let now = jsNow ()
|
let now = jsNow ()
|
||||||
{ Request.empty with
|
{ Request.empty with
|
||||||
requestId = reqId
|
requestId = reqId
|
||||||
userId = usrId
|
userId = usrId
|
||||||
enteredOn = now
|
enteredOn = now
|
||||||
snoozedUntil = 0L
|
showAfter = now
|
||||||
|
recurType = r.recurType
|
||||||
|
recurCount = r.recurCount
|
||||||
}
|
}
|
||||||
|> db.AddEntry
|
|> db.AddEntry
|
||||||
{ History.empty with
|
{ History.empty with
|
||||||
|
@ -144,9 +183,8 @@ module Request =
|
||||||
}
|
}
|
||||||
|> db.AddEntry
|
|> db.AddEntry
|
||||||
let! _ = db.SaveChangesAsync ()
|
let! _ = db.SaveChangesAsync ()
|
||||||
let! req = db.TryJournalById reqId usrId
|
match! db.TryJournalById reqId usrId with
|
||||||
match req with
|
| Some req -> return! (setStatusCode 201 >=> json req) next ctx
|
||||||
| Some rqst -> return! (setStatusCode 201 >=> json rqst) next ctx
|
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,18 +193,22 @@ module Request =
|
||||||
authorize
|
authorize
|
||||||
>=> fun next ctx ->
|
>=> fun next ctx ->
|
||||||
task {
|
task {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let! req = db.TryRequestById reqId (userId ctx)
|
match! db.TryRequestById reqId (userId ctx) with
|
||||||
match req with
|
| Some req ->
|
||||||
| Some _ ->
|
|
||||||
let! hist = ctx.BindJsonAsync<Models.HistoryEntry> ()
|
let! hist = ctx.BindJsonAsync<Models.HistoryEntry> ()
|
||||||
|
let now = jsNow ()
|
||||||
{ History.empty with
|
{ History.empty with
|
||||||
requestId = reqId
|
requestId = reqId
|
||||||
asOf = jsNow ()
|
asOf = now
|
||||||
status = hist.status
|
status = hist.status
|
||||||
text = match hist.updateText with null | "" -> None | x -> Some x
|
text = match hist.updateText with null | "" -> None | x -> Some x
|
||||||
}
|
}
|
||||||
|> db.AddEntry
|
|> db.AddEntry
|
||||||
|
match hist.status with
|
||||||
|
| "Prayed" ->
|
||||||
|
db.UpdateEntry { req with showAfter = now + (recurrence.[req.recurType] * int64 req.recurCount) }
|
||||||
|
| _ -> ()
|
||||||
let! _ = db.SaveChangesAsync ()
|
let! _ = db.SaveChangesAsync ()
|
||||||
return! created next ctx
|
return! created next ctx
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
|
@ -177,15 +219,14 @@ module Request =
|
||||||
authorize
|
authorize
|
||||||
>=> fun next ctx ->
|
>=> fun next ctx ->
|
||||||
task {
|
task {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let! req = db.TryRequestById reqId (userId ctx)
|
match! db.TryRequestById reqId (userId ctx) with
|
||||||
match req with
|
|
||||||
| Some _ ->
|
| Some _ ->
|
||||||
let! notes = ctx.BindJsonAsync<Models.NoteEntry> ()
|
let! notes = ctx.BindJsonAsync<Models.NoteEntry> ()
|
||||||
{ Note.empty with
|
{ Note.empty with
|
||||||
requestId = reqId
|
requestId = reqId
|
||||||
asOf = jsNow ()
|
asOf = jsNow ()
|
||||||
notes = notes.notes
|
notes = notes.notes
|
||||||
}
|
}
|
||||||
|> db.AddEntry
|
|> db.AddEntry
|
||||||
let! _ = db.SaveChangesAsync ()
|
let! _ = db.SaveChangesAsync ()
|
||||||
|
@ -206,20 +247,8 @@ module Request =
|
||||||
authorize
|
authorize
|
||||||
>=> fun next ctx ->
|
>=> fun next ctx ->
|
||||||
task {
|
task {
|
||||||
let! req = (db ctx).TryJournalById reqId (userId ctx)
|
match! (db ctx).TryJournalById reqId (userId ctx) with
|
||||||
match req with
|
| Some req -> return! json req next ctx
|
||||||
| Some r -> return! json r next ctx
|
|
||||||
| None -> return! Error.notFound next ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
/// GET /api/request/[req-id]/complete
|
|
||||||
let getComplete reqId : HttpHandler =
|
|
||||||
authorize
|
|
||||||
>=> fun next ctx ->
|
|
||||||
task {
|
|
||||||
let! req = (db ctx).TryCompleteRequestById reqId (userId ctx)
|
|
||||||
match req with
|
|
||||||
| Some r -> return! json r next ctx
|
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,9 +257,8 @@ module Request =
|
||||||
authorize
|
authorize
|
||||||
>=> fun next ctx ->
|
>=> fun next ctx ->
|
||||||
task {
|
task {
|
||||||
let! req = (db ctx).TryFullRequestById reqId (userId ctx)
|
match! (db ctx).TryFullRequestById reqId (userId ctx) with
|
||||||
match req with
|
| Some req -> return! json req next ctx
|
||||||
| Some r -> return! json r next ctx
|
|
||||||
| None -> return! Error.notFound next ctx
|
| None -> return! Error.notFound next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,17 +271,48 @@ module Request =
|
||||||
return! json notes next ctx
|
return! json notes next ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
/// POST /api/request/[req-id]/snooze
|
/// PATCH /api/request/[req-id]/show
|
||||||
let snooze reqId : HttpHandler =
|
let show reqId : HttpHandler =
|
||||||
authorize
|
authorize
|
||||||
>=> fun next ctx ->
|
>=> fun next ctx ->
|
||||||
task {
|
task {
|
||||||
let db = db ctx
|
let db = db ctx
|
||||||
let! req = db.TryRequestById reqId (userId ctx)
|
match! db.TryRequestById reqId (userId ctx) with
|
||||||
match req with
|
| Some req ->
|
||||||
| Some r ->
|
let! show = ctx.BindJsonAsync<Models.Show> ()
|
||||||
let! until = ctx.BindJsonAsync<Models.SnoozeUntil> ()
|
{ req with showAfter = show.showAfter }
|
||||||
{ r with snoozedUntil = until.until }
|
|> db.UpdateEntry
|
||||||
|
let! _ = db.SaveChangesAsync ()
|
||||||
|
return! setStatusCode 204 next ctx
|
||||||
|
| None -> return! Error.notFound next ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PATCH /api/request/[req-id]/snooze
|
||||||
|
let snooze reqId : HttpHandler =
|
||||||
|
authorize
|
||||||
|
>=> fun next ctx ->
|
||||||
|
task {
|
||||||
|
let db = db ctx
|
||||||
|
match! db.TryRequestById reqId (userId ctx) with
|
||||||
|
| Some req ->
|
||||||
|
let! until = ctx.BindJsonAsync<Models.SnoozeUntil> ()
|
||||||
|
{ req with snoozedUntil = until.until; showAfter = until.until }
|
||||||
|
|> db.UpdateEntry
|
||||||
|
let! _ = db.SaveChangesAsync ()
|
||||||
|
return! setStatusCode 204 next ctx
|
||||||
|
| None -> return! Error.notFound next ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PATCH /api/request/[req-id]/recurrence
|
||||||
|
let updateRecurrence reqId : HttpHandler =
|
||||||
|
authorize
|
||||||
|
>=> fun next ctx ->
|
||||||
|
task {
|
||||||
|
let db = db ctx
|
||||||
|
match! db.TryRequestById reqId (userId ctx) with
|
||||||
|
| Some req ->
|
||||||
|
let! recur = ctx.BindJsonAsync<Models.Recurrence> ()
|
||||||
|
{ req with recurType = recur.recurType; recurCount = recur.recurCount }
|
||||||
|> db.UpdateEntry
|
|> db.UpdateEntry
|
||||||
let! _ = db.SaveChangesAsync ()
|
let! _ = db.SaveChangesAsync ()
|
||||||
return! setStatusCode 204 next ctx
|
return! setStatusCode 204 next ctx
|
||||||
|
|
|
@ -53,16 +53,22 @@ module Configure =
|
||||||
/// Routes for the available URLs within myPrayerJournal
|
/// Routes for the available URLs within myPrayerJournal
|
||||||
let webApp =
|
let webApp =
|
||||||
router Handlers.Error.notFound [
|
router Handlers.Error.notFound [
|
||||||
route "/" (htmlFile "wwwroot/index.html")
|
route "/" Handlers.Vue.app
|
||||||
subRoute "/api/" [
|
subRoute "/api/" [
|
||||||
GET [
|
GET [
|
||||||
route "journal" Handlers.Journal.journal
|
route "journal" Handlers.Journal.journal
|
||||||
subRoute "request" [
|
subRoute "request" [
|
||||||
route "s/answered" Handlers.Request.answered
|
route "s/answered" Handlers.Request.answered
|
||||||
routef "/%s/complete" Handlers.Request.getComplete
|
routef "/%s/full" Handlers.Request.getFull
|
||||||
routef "/%s/full" Handlers.Request.getFull
|
routef "/%s/notes" Handlers.Request.getNotes
|
||||||
routef "/%s/notes" Handlers.Request.getNotes
|
routef "/%s" Handlers.Request.get
|
||||||
routef "/%s" Handlers.Request.get
|
]
|
||||||
|
]
|
||||||
|
PATCH [
|
||||||
|
subRoute "request" [
|
||||||
|
routef "/%s/recurrence" Handlers.Request.updateRecurrence
|
||||||
|
routef "/%s/show" Handlers.Request.show
|
||||||
|
routef "/%s/snooze" Handlers.Request.snooze
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
POST [
|
POST [
|
||||||
|
@ -70,7 +76,6 @@ module Configure =
|
||||||
route "" Handlers.Request.add
|
route "" Handlers.Request.add
|
||||||
routef "/%s/history" Handlers.Request.addHistory
|
routef "/%s/history" Handlers.Request.addHistory
|
||||||
routef "/%s/note" Handlers.Request.addNote
|
routef "/%s/note" Handlers.Request.addNote
|
||||||
routef "/%s/snooze" Handlers.Request.snooze
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
|
@ -17,14 +17,11 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"auth0-js": "^9.7.3",
|
"auth0-js": "^9.7.3",
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"bootstrap": "^4.1.3",
|
"moment": "^2.18.1",
|
||||||
"bootstrap-vue": "^2.0.0-rc.11",
|
"pug": "^2.0.1",
|
||||||
"moment": "^2.22.2",
|
"vue": "^2.5.15",
|
||||||
"pug": "^2.0.3",
|
"vue-progressbar": "^0.7.3",
|
||||||
"vue": "^2.5.17",
|
"vue-router": "^3.0.0",
|
||||||
"vue-awesome": "^2.3.3",
|
|
||||||
"vue-progressbar": "^0.7.5",
|
|
||||||
"vue-router": "^3.0.1",
|
|
||||||
"vue-toast": "^3.1.0",
|
"vue-toast": "^3.1.0",
|
||||||
"vuex": "^3.0.1"
|
"vuex": "^3.0.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,25 +1,28 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
#app
|
#app(role='application')
|
||||||
navigation
|
navigation
|
||||||
#content.container
|
#content
|
||||||
router-view
|
router-view
|
||||||
vue-progress-bar
|
vue-progress-bar
|
||||||
toast(ref='toast')
|
toast(ref='toast')
|
||||||
footer
|
footer.mpj-text-right.mpj-muted-text
|
||||||
p.text-right.text-muted
|
p
|
||||||
| myPrayerJournal v{{ version }}
|
| myPrayerJournal v{{ version }}
|
||||||
br
|
br
|
||||||
em: small.
|
em: small.
|
||||||
#[router-link(:to="{ name: 'PrivacyPolicy' }") Privacy Policy] •
|
#[router-link(:to="{ name: 'PrivacyPolicy' }") Privacy Policy] •
|
||||||
#[router-link(:to="{ name: 'TermsOfService' }") Terms of Service] •
|
#[router-link(:to="{ name: 'TermsOfService' }") Terms of Service] •
|
||||||
#[a(href='https://github.com/bit-badger/myprayerjournal') Developed] and hosted by
|
#[a(href='https://github.com/bit-badger/myprayerjournal' target='_blank') Developed] and hosted by
|
||||||
#[a(href='https://bitbadger.solutions') Bit Badger Solutions]
|
#[a(href='https://bitbadger.solutions' target='_blank') Bit Badger Solutions]
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
'use strict'
|
'use strict'
|
||||||
import Navigation from './components/Navigation.vue'
|
|
||||||
|
import Navigation from './components/common/Navigation.vue'
|
||||||
|
|
||||||
import { version } from '../package.json'
|
import { version } from '../package.json'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
components: {
|
components: {
|
||||||
|
@ -42,9 +45,76 @@ export default {
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html, body {
|
||||||
background-color: whitesmoke;
|
background-color: whitesmoke;
|
||||||
|
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
||||||
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
padding-top: 60px;
|
padding-top: 50px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5 {
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
h5 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
input, textarea, select {
|
||||||
|
border-radius: .25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;
|
||||||
|
}
|
||||||
|
input, select {
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
button,
|
||||||
|
a[role="button"] {
|
||||||
|
border: solid 1px #050;
|
||||||
|
border-radius: .5rem;
|
||||||
|
background-color: rgb(235, 235, 235);
|
||||||
|
padding: .25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
a[role="button"]:link,
|
||||||
|
a[role="button"]:visited {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
button.primary,
|
||||||
|
a[role="button"].primary {
|
||||||
|
background-color: white;
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
|
button:hover,
|
||||||
|
a[role="button"]:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #050;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
label.normal {
|
||||||
|
font-variant: unset;
|
||||||
|
font-size: unset;
|
||||||
}
|
}
|
||||||
footer {
|
footer {
|
||||||
border-top: solid 1px lightgray;
|
border-top: solid 1px lightgray;
|
||||||
|
@ -56,14 +126,116 @@ footer p {
|
||||||
}
|
}
|
||||||
a:link, a:visited {
|
a:link, a:visited {
|
||||||
color: #050;
|
color: #050;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.mpj-main-content {
|
||||||
|
max-width: 60rem;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.mpj-main-content-wide {
|
||||||
|
margin: .5rem;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 21rem) {
|
||||||
|
.mpj-main-content-wide {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.mpj-request-text {
|
.mpj-request-text {
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
.bg-mpj {
|
.mpj-request-list p {
|
||||||
|
border-top: solid 1px lightgray;
|
||||||
|
}
|
||||||
|
.mpj-request-list p:first-child {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.mpj-request-log {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.mpj-request-log thead th {
|
||||||
|
border-top: solid 1px lightgray;
|
||||||
|
border-bottom: solid 2px lightgray;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.mpj-request-log tbody td {
|
||||||
|
border-bottom: dotted 1px lightgray;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.mpj-bg {
|
||||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#050), to(whitesmoke));
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#050), to(whitesmoke));
|
||||||
background-image: -webkit-linear-gradient(top, #050, whitesmoke);
|
background-image: -webkit-linear-gradient(top, #050, whitesmoke);
|
||||||
background-image: -moz-linear-gradient(top, #050, whitesmoke);
|
background-image: -moz-linear-gradient(top, #050, whitesmoke);
|
||||||
background-image: linear-gradient(to bottom, #050, whitesmoke);
|
background-image: linear-gradient(to bottom, #050, whitesmoke);
|
||||||
}
|
}
|
||||||
</style>
|
.mpj-text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.mpj-text-nowrap {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.mpj-text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.mpj-muted-text {
|
||||||
|
color: rgba(0, 0, 0, .6);
|
||||||
|
}
|
||||||
|
.mpj-narrow {
|
||||||
|
max-width: 40rem;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.mpj-skinny {
|
||||||
|
max-width: 20rem;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.mpj-full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.mpj-modal {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 8;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0, 0, 0, .4);
|
||||||
|
}
|
||||||
|
.mpj-modal-content {
|
||||||
|
background-color: whitesmoke;
|
||||||
|
border: solid 1px #050;
|
||||||
|
border-radius: .5rem;
|
||||||
|
animation-name: animatetop;
|
||||||
|
animation-duration: 0.4s;
|
||||||
|
padding: 1rem;
|
||||||
|
margin-top: 4rem;
|
||||||
|
}
|
||||||
|
@keyframes animatetop {
|
||||||
|
from {
|
||||||
|
top: -300px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
top: 0;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mpj-modal-content header {
|
||||||
|
margin: -1rem -1rem .5rem;
|
||||||
|
border-radius: .4rem;
|
||||||
|
}
|
||||||
|
.mpj-modal-content header h5 {
|
||||||
|
color: white;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.mpj-margin {
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
.material-icons {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
const http = axios.create({
|
const http = axios.create({
|
||||||
|
@ -30,8 +32,10 @@ export default {
|
||||||
/**
|
/**
|
||||||
* Add a new prayer request
|
* Add a new prayer request
|
||||||
* @param {string} requestText The text of the request to be added
|
* @param {string} requestText The text of the request to be added
|
||||||
|
* @param {string} recurType The type of recurrence for this request
|
||||||
|
* @param {number} recurCount The number of intervals of recurrence
|
||||||
*/
|
*/
|
||||||
addRequest: requestText => http.post('request', { requestText }),
|
addRequest: (requestText, recurType, recurCount) => http.post('request', { requestText, recurType, recurCount }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all answered requests, along with the text they had when it was answered
|
* Get all answered requests, along with the text they had when it was answered
|
||||||
|
@ -39,7 +43,7 @@ export default {
|
||||||
getAnsweredRequests: () => http.get('requests/answered'),
|
getAnsweredRequests: () => http.get('requests/answered'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a prayer request (full; includes all history)
|
* Get a prayer request (full; includes all history and notes)
|
||||||
* @param {string} requestId The Id of the request to retrieve
|
* @param {string} requestId The Id of the request to retrieve
|
||||||
*/
|
*/
|
||||||
getFullRequest: requestId => http.get(`request/${requestId}/full`),
|
getFullRequest: requestId => http.get(`request/${requestId}/full`),
|
||||||
|
@ -56,30 +60,39 @@ export default {
|
||||||
*/
|
*/
|
||||||
getRequest: requestId => http.get(`request/${requestId}`),
|
getRequest: requestId => http.get(`request/${requestId}`),
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a complete request; equivalent of "full" and "notes" combined
|
|
||||||
*/
|
|
||||||
getRequestComplete: requestId => http.get(`request/${requestId}/complete`),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all prayer requests and their most recent updates
|
* Get all prayer requests and their most recent updates
|
||||||
*/
|
*/
|
||||||
journal: () => http.get('journal'),
|
journal: () => http.get('journal'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Snooze a request until the given time
|
* Show a request after the given date (used for "show now")
|
||||||
* @param requestId {string} The ID of the prayer request to be snoozed
|
* @param {string} requestId The ID of the request which should be shown
|
||||||
* @param until {number} The ticks until which the request should be snoozed
|
* @param {number} showAfter The ticks after which the request should be shown
|
||||||
*/
|
*/
|
||||||
snoozeRequest: (requestId, until) => http.post(`request/${requestId}/snooze`, { until }),
|
showRequest: (requestId, showAfter) => http.patch(`request/${requestId}/show`, { showAfter }),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Snooze a request until the given time
|
||||||
|
* @param {string} requestId The ID of the prayer request to be snoozed
|
||||||
|
* @param {number} until The ticks until which the request should be snoozed
|
||||||
|
*/
|
||||||
|
snoozeRequest: (requestId, until) => http.patch(`request/${requestId}/snooze`, { until }),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update recurrence for a prayer request
|
||||||
|
* @param {string} requestId The ID of the prayer request for which recurrence is being updated
|
||||||
|
* @param {string} recurType The type of recurrence to set
|
||||||
|
* @param {number} recurCount The number of recurrence intervals to set
|
||||||
|
*/
|
||||||
|
updateRecurrence: (requestId, recurType, recurCount) =>
|
||||||
|
http.patch(`request/${requestId}/recurrence`, { recurType, recurCount }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a prayer request
|
* Update a prayer request
|
||||||
* @param request The request (should have requestId, status, and updateText properties)
|
* @param {string} requestId The ID of the request to be updated
|
||||||
|
* @param {string} status The status of the update
|
||||||
|
* @param {string} updateText The text of the update (optional)
|
||||||
*/
|
*/
|
||||||
updateRequest: request => http.post(`request/${request.requestId}/history`, {
|
updateRequest: (requestId, status, updateText) => http.post(`request/${requestId}/history`, { status, updateText })
|
||||||
status: request.status,
|
|
||||||
updateText: request.updateText
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
<template lang="pug">
|
|
||||||
article
|
|
||||||
page-title(title='Answered Request')
|
|
||||||
p(v-if='!request') Loading request...
|
|
||||||
template(v-if='request')
|
|
||||||
p.
|
|
||||||
Answered {{ formatDate(answered) }} (#[date-from-now(:value='answered')])
|
|
||||||
#[small: em.text-muted prayed {{ prayedCount }} times, open {{ openDays }} days]
|
|
||||||
p.mpj-request-text {{ lastText }}
|
|
||||||
b-table(small hover :fields='fields' :items='log')
|
|
||||||
template(slot='action' scope='data').
|
|
||||||
{{ data.item.status }} on #[span.text-nowrap {{ formatDate(data.item.asOf) }}]
|
|
||||||
template(slot='text' scope='data' v-if='data.item.text') {{ data.item.text.fields[0] }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
import moment from 'moment'
|
|
||||||
|
|
||||||
import api from '@/api'
|
|
||||||
|
|
||||||
const asOfDesc = (a, b) => b.asOf - a.asOf
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'answer-detail',
|
|
||||||
props: {
|
|
||||||
id: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
request: null,
|
|
||||||
fields: [
|
|
||||||
{ key: 'action', label: 'Action' },
|
|
||||||
{ key: 'text', label: 'Update / Notes' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
answered () {
|
|
||||||
return this.request.history.find(hist => hist.status === 'Answered').asOf
|
|
||||||
},
|
|
||||||
lastText () {
|
|
||||||
return this.request.history
|
|
||||||
.filter(hist => hist.text)
|
|
||||||
.sort(asOfDesc)[0].text.fields[0]
|
|
||||||
},
|
|
||||||
log () {
|
|
||||||
return (this.request.notes || [])
|
|
||||||
.map(note => ({ asOf: note.asOf, text: { case: 'Some', fields: [ note.notes ] }, status: 'Notes' }))
|
|
||||||
.concat(this.request.history)
|
|
||||||
.sort(asOfDesc)
|
|
||||||
.slice(1)
|
|
||||||
},
|
|
||||||
openDays () {
|
|
||||||
return Math.floor(
|
|
||||||
(this.answered - this.request.history.find(hist => hist.status === 'Created').asOf) / 1000 / 60 / 60 / 24)
|
|
||||||
},
|
|
||||||
prayedCount () {
|
|
||||||
return this.request.history.filter(hist => hist.status === 'Prayed').length
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async mounted () {
|
|
||||||
this.$Progress.start()
|
|
||||||
try {
|
|
||||||
const req = await api.getRequestComplete(this.id)
|
|
||||||
this.request = req.data
|
|
||||||
this.$Progress.finish()
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
this.$Progress.fail()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
formatDate (asOf) {
|
|
||||||
return moment(asOf).format('LL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
article
|
article.mpj-main-content(role='main')
|
||||||
page-title(title='Welcome!'
|
page-title(title='Welcome!'
|
||||||
hideOnPage='true')
|
hideOnPage='true')
|
||||||
p
|
p
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
article
|
article.mpj-main-content-wide(role='main')
|
||||||
page-title(:title='title')
|
page-title(:title='title')
|
||||||
p(v-if='isLoadingJournal') Loading your prayer journal...
|
p(v-if='isLoadingJournal') Loading your prayer journal...
|
||||||
template(v-if='!isLoadingJournal')
|
template(v-else)
|
||||||
new-request
|
.mpj-text-center
|
||||||
|
router-link(:to="{ name: 'EditRequest', params: { id: 'new' } }"
|
||||||
|
role='button').
|
||||||
|
#[md-icon(icon='add_box')] Add a New Request
|
||||||
br
|
br
|
||||||
b-row(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.requestId'
|
:key='request.requestId'
|
||||||
:request='request'
|
:request='request'
|
||||||
:events='eventBus'
|
:events='eventBus'
|
||||||
:toast='toast')
|
:toast='toast')
|
||||||
p.text-center(v-if='journal.length === 0'): em.
|
p.text-center(v-else): em.
|
||||||
No requests found; click the “Add a New Request” button to add one
|
No requests found; click the “Add a New Request” button to add one
|
||||||
edit-request(:events='eventBus'
|
|
||||||
:toast='toast')
|
|
||||||
notes-edit(:events='eventBus'
|
notes-edit(:events='eventBus'
|
||||||
:toast='toast')
|
:toast='toast')
|
||||||
full-request(:events='eventBus')
|
|
||||||
snooze-request(:events='eventBus'
|
snooze-request(:events='eventBus'
|
||||||
:toast='toast')
|
:toast='toast')
|
||||||
</template>
|
</template>
|
||||||
|
@ -28,9 +28,6 @@ article
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
import EditRequest from './request/EditRequest'
|
|
||||||
import FullRequest from './request/FullRequest'
|
|
||||||
import NewRequest from './request/NewRequest'
|
|
||||||
import NotesEdit from './request/NotesEdit'
|
import NotesEdit from './request/NotesEdit'
|
||||||
import RequestCard from './request/RequestCard'
|
import RequestCard from './request/RequestCard'
|
||||||
import SnoozeRequest from './request/SnoozeRequest'
|
import SnoozeRequest from './request/SnoozeRequest'
|
||||||
|
@ -40,9 +37,6 @@ import actions from '@/store/action-types'
|
||||||
export default {
|
export default {
|
||||||
name: 'journal',
|
name: 'journal',
|
||||||
components: {
|
components: {
|
||||||
EditRequest,
|
|
||||||
FullRequest,
|
|
||||||
NewRequest,
|
|
||||||
NotesEdit,
|
NotesEdit,
|
||||||
RequestCard,
|
RequestCard,
|
||||||
SnoozeRequest
|
SnoozeRequest
|
||||||
|
@ -67,3 +61,12 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.mpj-journal {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,56 +0,0 @@
|
||||||
<template lang="pug">
|
|
||||||
b-navbar(toggleable='sm'
|
|
||||||
type='dark'
|
|
||||||
variant='mpj'
|
|
||||||
fixed='top')
|
|
||||||
b-nav-toggle(target='nav_collapse')
|
|
||||||
b-navbar-brand(to='/')
|
|
||||||
span(style='font-weight:100;') my
|
|
||||||
span(style='font-weight:600;') Prayer
|
|
||||||
span(style='font-weight:700;') Journal
|
|
||||||
b-collapse#nav_collapse(is-nav)
|
|
||||||
b-navbar-nav
|
|
||||||
b-nav-item(v-if='isAuthenticated'
|
|
||||||
to='/journal') Journal
|
|
||||||
b-nav-item(v-if='hasSnoozed'
|
|
||||||
to='/snoozed') Snoozed
|
|
||||||
b-nav-item(v-if='isAuthenticated'
|
|
||||||
to='/answered') Answered
|
|
||||||
b-nav-item(v-if='isAuthenticated'): a(@click.stop='logOff()') Log Off
|
|
||||||
b-nav-item(v-if='!isAuthenticated'): a(@click.stop='logOn()') Log On
|
|
||||||
b-nav-item(href='https://bit-badger.github.io/myPrayerJournal/'
|
|
||||||
target='_blank'
|
|
||||||
@click.stop='') Docs
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import AuthService from '@/auth/AuthService'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'navigation',
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
auth0: new AuthService()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
hasSnoozed () {
|
|
||||||
return this.isAuthenticated &&
|
|
||||||
Array.isArray(this.journal) &&
|
|
||||||
this.journal.filter(req => req.snoozedUntil > Date.now()).length > 0
|
|
||||||
},
|
|
||||||
...mapState([ 'journal', 'isAuthenticated' ])
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
logOn () {
|
|
||||||
this.auth0.login()
|
|
||||||
},
|
|
||||||
logOff () {
|
|
||||||
this.auth0.logout(this.$store, this.$router)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,76 +0,0 @@
|
||||||
<template lang="pug">
|
|
||||||
article
|
|
||||||
page-title(title='Snoozed Requests')
|
|
||||||
p(v-if='!loaded') Loading journal...
|
|
||||||
div(v-if='loaded').mpj-snoozed-list
|
|
||||||
p.text-center(v-if='requests.length === 0'): em.
|
|
||||||
No snoozed requests found; return to #[router-link(:to='{ name: "Journal" } ') your journal]
|
|
||||||
p.mpj-snoozed-text(v-for='req in requests' :key='req.requestId')
|
|
||||||
| {{ req.text }}
|
|
||||||
br
|
|
||||||
br
|
|
||||||
b-btn(@click='cancelSnooze(req.requestId)'
|
|
||||||
size='sm'
|
|
||||||
variant='outline-secondary')
|
|
||||||
icon(name='times')
|
|
||||||
= ' Cancel Snooze'
|
|
||||||
small.text-muted: em.
|
|
||||||
Snooze expires #[date-from-now(:value='req.snoozedUntil')]
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use static'
|
|
||||||
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'answered',
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
requests: [],
|
|
||||||
loaded: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
toast () {
|
|
||||||
return this.$parent.$refs.toast
|
|
||||||
},
|
|
||||||
...mapState(['journal', 'isLoadingJournal'])
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async ensureJournal () {
|
|
||||||
if (!Array.isArray(this.journal)) {
|
|
||||||
this.loaded = false
|
|
||||||
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
|
||||||
}
|
|
||||||
this.requests = this.journal
|
|
||||||
.filter(req => req.snoozedUntil > Date.now())
|
|
||||||
.sort((a, b) => a.snoozedUntil - b.snoozedUntil)
|
|
||||||
this.loaded = true
|
|
||||||
},
|
|
||||||
async cancelSnooze (requestId) {
|
|
||||||
await this.$store.dispatch(actions.SNOOZE_REQUEST, {
|
|
||||||
progress: this.$Progress,
|
|
||||||
requestId: requestId,
|
|
||||||
until: 0
|
|
||||||
})
|
|
||||||
this.toast.showToast('Request un-snoozed', { theme: 'success' })
|
|
||||||
this.ensureJournal()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async mounted () {
|
|
||||||
await this.ensureJournal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.mpj-snoozed-list p {
|
|
||||||
border-top: solid 1px lightgray;
|
|
||||||
}
|
|
||||||
.mpj-snoozed-list p:first-child {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
15
src/app/src/components/common/MaterialDesignIcon.vue
Normal file
15
src/app/src/components/common/MaterialDesignIcon.vue
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<template lang="pug">
|
||||||
|
i.material-icons(v-html='icon')
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'md-icon',
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
96
src/app/src/components/common/Navigation.vue
Normal file
96
src/app/src/components/common/Navigation.vue
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<template lang="pug">
|
||||||
|
nav.mpj-top-nav.mpj-bg(role='menubar')
|
||||||
|
router-link.title(:to="{ name: 'Home' }"
|
||||||
|
role='menuitem')
|
||||||
|
span(style='font-weight:100;') my
|
||||||
|
span(style='font-weight:600;') Prayer
|
||||||
|
span(style='font-weight:700;') Journal
|
||||||
|
router-link(v-if='isAuthenticated'
|
||||||
|
:to="{ name: 'Journal' }"
|
||||||
|
role='menuitem') Journal
|
||||||
|
router-link(v-if='isAuthenticated'
|
||||||
|
:to="{ name: 'ActiveRequests' }"
|
||||||
|
role='menuitem') Active
|
||||||
|
router-link(v-if='hasSnoozed'
|
||||||
|
:to="{ name: 'SnoozedRequests' }"
|
||||||
|
role='menuitem') Snoozed
|
||||||
|
router-link(v-if='isAuthenticated'
|
||||||
|
:to="{ name: 'AnsweredRequests' }"
|
||||||
|
role='menuitem') Answered
|
||||||
|
a(v-if='isAuthenticated'
|
||||||
|
href='#'
|
||||||
|
role='menuitem'
|
||||||
|
@click.stop='logOff()') Log Off
|
||||||
|
a(v-if='!isAuthenticated'
|
||||||
|
href='#'
|
||||||
|
role='menuitem'
|
||||||
|
@click.stop='logOn()') Log On
|
||||||
|
a(href='https://bit-badger.github.io/myPrayerJournal/'
|
||||||
|
target='_blank'
|
||||||
|
role='menuitem'
|
||||||
|
@click.stop='') Docs
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
|
import AuthService from '@/auth/AuthService'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'navigation',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
auth0: new AuthService()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasSnoozed () {
|
||||||
|
return this.isAuthenticated &&
|
||||||
|
Array.isArray(this.journal) &&
|
||||||
|
this.journal.filter(req => req.snoozedUntil > Date.now()).length > 0
|
||||||
|
},
|
||||||
|
...mapState([ 'journal', 'isAuthenticated' ])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
logOn () {
|
||||||
|
this.auth0.login()
|
||||||
|
},
|
||||||
|
logOff () {
|
||||||
|
this.auth0.logout(this.$store, this.$router)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.mpj-top-nav {
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
align-items: center;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding-left: .5rem;
|
||||||
|
min-height: 50px;
|
||||||
|
}
|
||||||
|
.mpj-top-nav a:link,
|
||||||
|
.mpj-top-nav a:visited {
|
||||||
|
text-decoration: none;
|
||||||
|
color: rgba(255, 255, 255, .75);
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
.mpj-top-nav a:link.router-link-active,
|
||||||
|
.mpj-top-nav a:visited.router-link-active,
|
||||||
|
.mpj-top-nav a:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.mpj-top-nav .title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: white;
|
||||||
|
padding-left: 1.25rem;
|
||||||
|
padding-right: 1.25rem;
|
||||||
|
}
|
||||||
|
</style>
|
59
src/app/src/components/request/ActiveRequests.vue
Normal file
59
src/app/src/components/request/ActiveRequests.vue
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<template lang="pug">
|
||||||
|
article.mpj-main-content(role='main')
|
||||||
|
page-title(title='Active Requests')
|
||||||
|
div(v-if='loaded').mpj-request-list
|
||||||
|
p.mpj-text-center(v-if='requests.length === 0'): em.
|
||||||
|
No active requests found; return to #[router-link(:to='{ name: "Journal" } ') your journal]
|
||||||
|
request-list-item(v-for='req in requests'
|
||||||
|
:key='req.requestId'
|
||||||
|
:request='req'
|
||||||
|
:toast='toast')
|
||||||
|
p(v-else) Loading journal...
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
|
import RequestListItem from '@/components/request/RequestListItem'
|
||||||
|
|
||||||
|
import actions from '@/store/action-types'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'active-requests',
|
||||||
|
components: {
|
||||||
|
RequestListItem
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
requests: [],
|
||||||
|
loaded: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
toast () {
|
||||||
|
return this.$parent.$refs.toast
|
||||||
|
},
|
||||||
|
...mapState(['journal', 'isLoadingJournal'])
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.$on('requestUnsnoozed', this.ensureJournal)
|
||||||
|
this.$on('requestNowShown', this.ensureJournal)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async ensureJournal () {
|
||||||
|
if (!Array.isArray(this.journal)) {
|
||||||
|
this.loaded = false
|
||||||
|
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
||||||
|
}
|
||||||
|
this.requests = this.journal
|
||||||
|
.sort((a, b) => a.showAfter - b.showAfter)
|
||||||
|
this.loaded = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted () {
|
||||||
|
await this.ensureJournal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,30 +1,28 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
article
|
article.mpj-main-content(role='main')
|
||||||
page-title(title='Answered Requests')
|
page-title(title='Answered Requests')
|
||||||
p(v-if='!loaded') Loading answered requests...
|
div(v-if='loaded').mpj-request-list
|
||||||
div(v-if='loaded').mpj-answered-list
|
|
||||||
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
|
||||||
p.mpj-request-text(v-for='req in requests' :key='req.requestId')
|
request-list-item(v-for='req in requests'
|
||||||
| {{ req.text }}
|
:key='req.requestId'
|
||||||
br
|
:request='req'
|
||||||
br
|
:toast='toast')
|
||||||
b-btn(:to='{ name: "AnsweredDetail", params: { id: req.requestId }}'
|
p(v-else) Loading answered requests...
|
||||||
size='sm'
|
|
||||||
variant='outline-secondary')
|
|
||||||
icon(name='search')
|
|
||||||
= ' View Full Request'
|
|
||||||
small.text-muted: em.
|
|
||||||
Answered #[date-from-now(:value='req.asOf')]
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
'use static'
|
'use strict'
|
||||||
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
|
||||||
|
import RequestListItem from '@/components/request/RequestListItem'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'answered',
|
name: 'answered-requests',
|
||||||
|
components: {
|
||||||
|
RequestListItem
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
requests: [],
|
requests: [],
|
||||||
|
@ -52,12 +50,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.mpj-answered-list p {
|
|
||||||
border-top: solid 1px lightgray;
|
|
||||||
}
|
|
||||||
.mpj-answered-list p:first-child {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,89 +1,204 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
b-modal(v-model='editVisible'
|
article.mpj-main-content(role='main')
|
||||||
header-bg-variant='mpj'
|
page-title(:title='title')
|
||||||
header-text-variant='light'
|
.mpj-narrow
|
||||||
size='lg'
|
label(for='request_text')
|
||||||
title='Edit Prayer Request'
|
| Prayer Request
|
||||||
@edit='openDialog()'
|
br
|
||||||
@shows='focusRequestText')
|
textarea(v-model='form.requestText'
|
||||||
b-form
|
:rows='10'
|
||||||
b-form-group(label='Prayer Request'
|
@blur='trimText()'
|
||||||
label-for='request_text')
|
autofocus).mpj-full-width
|
||||||
b-textarea#request_text(ref='toFocus'
|
br
|
||||||
v-model='form.requestText'
|
template(v-if='!isNew')
|
||||||
:rows='10'
|
label Also Mark As
|
||||||
@blur='trimText()')
|
br
|
||||||
b-form-group(label='Also Mark As')
|
label.normal
|
||||||
b-radio-group(v-model='form.status'
|
input(v-model='form.status'
|
||||||
buttons)
|
type='radio'
|
||||||
b-radio(value='Updated') Updated
|
name='status'
|
||||||
b-radio(value='Prayed') Prayed
|
value='Updated')
|
||||||
b-radio(value='Answered') Answered
|
| Updated
|
||||||
div.w-100.text-right(slot='modal-footer')
|
|
|
||||||
b-btn(variant='primary'
|
label.normal
|
||||||
@click='saveRequest()') Save
|
input(v-model='form.status'
|
||||||
|
type='radio'
|
||||||
|
name='status'
|
||||||
|
value='Prayed')
|
||||||
|
| Prayed
|
||||||
|
|
|
||||||
|
label.normal
|
||||||
|
input(v-model='form.status'
|
||||||
|
type='radio'
|
||||||
|
name='status'
|
||||||
|
value='Answered')
|
||||||
|
| Answered
|
||||||
|
br
|
||||||
|
label Recurrence
|
||||||
|
|
|
|
||||||
b-btn(variant='outline-secondary'
|
em.mpj-muted-text After prayer, request reappears...
|
||||||
@click='closeDialog()') Cancel
|
br
|
||||||
|
label.normal
|
||||||
|
input(v-model='form.recur.typ'
|
||||||
|
type='radio'
|
||||||
|
name='recur'
|
||||||
|
value='immediate')
|
||||||
|
| Immediately
|
||||||
|
|
|
||||||
|
label.normal
|
||||||
|
input(v-model='form.recur.typ'
|
||||||
|
type='radio'
|
||||||
|
name='recur'
|
||||||
|
value='other')
|
||||||
|
| Every...
|
||||||
|
input(v-model='form.recur.count'
|
||||||
|
type='number'
|
||||||
|
:disabled='!showRecurrence').mpj-recur-count
|
||||||
|
select(v-model='form.recur.other'
|
||||||
|
:disabled='!showRecurrence').mpj-recur-type
|
||||||
|
option(value='hours') hours
|
||||||
|
option(value='days') days
|
||||||
|
option(value='weeks') weeks
|
||||||
|
.mpj-text-right
|
||||||
|
button(:disabled='!isValidRecurrence'
|
||||||
|
@click.stop='saveRequest()').primary.
|
||||||
|
#[md-icon(icon='save')] Save
|
||||||
|
|
|
||||||
|
button(@click.stop='goBack()').
|
||||||
|
#[md-icon(icon='arrow_back')] Cancel
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import actions from '@/store/action-types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'edit-request',
|
name: 'edit-request',
|
||||||
props: {
|
props: {
|
||||||
toast: { required: true },
|
id: {
|
||||||
events: { required: true }
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
editVisible: false,
|
title: 'Edit Prayer Request',
|
||||||
|
isNew: false,
|
||||||
form: {
|
form: {
|
||||||
requestId: '',
|
requestId: '',
|
||||||
requestText: '',
|
requestText: '',
|
||||||
status: 'Updated'
|
status: 'Updated',
|
||||||
|
recur: {
|
||||||
|
typ: 'immediate',
|
||||||
|
other: '',
|
||||||
|
count: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
computed: {
|
||||||
this.events.$on('edit', this.openDialog)
|
isValidRecurrence () {
|
||||||
|
if (this.form.recur.typ === 'immediate') return true
|
||||||
|
const count = Number.parseInt(this.form.recur.count)
|
||||||
|
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 === 'days' && count > 365) return false
|
||||||
|
if (this.form.recur.other === 'weeks' && count > 52) return false
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
showRecurrence () {
|
||||||
|
return this.form.recur.typ !== 'immediate'
|
||||||
|
},
|
||||||
|
toast () {
|
||||||
|
return this.$parent.$refs.toast
|
||||||
|
},
|
||||||
|
...mapState(['journal'])
|
||||||
},
|
},
|
||||||
methods: {
|
async mounted () {
|
||||||
closeDialog () {
|
await this.ensureJournal()
|
||||||
|
if (this.id === 'new') {
|
||||||
|
this.title = 'Add Prayer Request'
|
||||||
|
this.isNew = true
|
||||||
this.form.requestId = ''
|
this.form.requestId = ''
|
||||||
this.form.requestText = ''
|
this.form.requestText = ''
|
||||||
|
this.form.status = 'Created'
|
||||||
|
this.form.recur.typ = 'immediate'
|
||||||
|
this.form.recur.other = ''
|
||||||
|
this.form.recur.count = ''
|
||||||
|
} else {
|
||||||
|
this.title = 'Edit Prayer Request'
|
||||||
|
this.isNew = false
|
||||||
|
if (this.journal.length === 0) {
|
||||||
|
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
||||||
|
}
|
||||||
|
const req = this.journal.filter(r => r.requestId === this.id)[0]
|
||||||
|
this.form.requestId = this.id
|
||||||
|
this.form.requestText = req.text
|
||||||
this.form.status = 'Updated'
|
this.form.status = 'Updated'
|
||||||
this.editVisible = false
|
if (req.recurType === 'immediate') {
|
||||||
},
|
this.form.recur.typ = 'immediate'
|
||||||
focusRequestText (e) {
|
this.form.recur.other = ''
|
||||||
this.$refs.toFocus.focus()
|
this.form.recur.count = ''
|
||||||
},
|
} else {
|
||||||
openDialog (request) {
|
this.form.recur.typ = 'other'
|
||||||
this.form.requestId = request.requestId
|
this.form.recur.other = req.recurType
|
||||||
this.form.requestText = request.text
|
this.form.recur.count = req.recurCount
|
||||||
this.editVisible = true
|
}
|
||||||
this.focusRequestText(null)
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
goBack () {
|
||||||
|
this.$router.go(-1)
|
||||||
},
|
},
|
||||||
trimText () {
|
trimText () {
|
||||||
this.form.requestText = this.form.requestText.trim()
|
this.form.requestText = this.form.requestText.trim()
|
||||||
},
|
},
|
||||||
async saveRequest () {
|
async ensureJournal () {
|
||||||
await this.$store.dispatch(actions.UPDATE_REQUEST, {
|
if (!Array.isArray(this.journal)) {
|
||||||
progress: this.$Progress,
|
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
||||||
requestId: this.form.requestId,
|
|
||||||
updateText: this.form.requestText,
|
|
||||||
status: this.form.status
|
|
||||||
})
|
|
||||||
if (this.form.status === 'Answered') {
|
|
||||||
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
|
|
||||||
} else {
|
|
||||||
this.toast.showToast('Request updated', { theme: 'success' })
|
|
||||||
}
|
}
|
||||||
this.closeDialog()
|
},
|
||||||
|
async saveRequest () {
|
||||||
|
if (this.isNew) {
|
||||||
|
await this.$store.dispatch(actions.ADD_REQUEST, {
|
||||||
|
progress: this.$Progress,
|
||||||
|
requestText: this.form.requestText,
|
||||||
|
recurType: this.form.recur.typ === 'immediate' ? 'immediate' : this.form.recur.other,
|
||||||
|
recurCount: this.form.recur.typ === 'immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
||||||
|
})
|
||||||
|
this.toast.showToast('New prayer request added', { theme: 'success' })
|
||||||
|
} else {
|
||||||
|
await this.$store.dispatch(actions.UPDATE_REQUEST, {
|
||||||
|
progress: this.$Progress,
|
||||||
|
requestId: this.form.requestId,
|
||||||
|
updateText: this.form.requestText,
|
||||||
|
status: this.form.status,
|
||||||
|
recurType: this.form.recur.typ === 'immediate' ? 'immediate' : this.form.recur.other,
|
||||||
|
recurCount: this.form.recur.typ === 'immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
||||||
|
})
|
||||||
|
if (this.form.status === 'Answered') {
|
||||||
|
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
|
||||||
|
} else {
|
||||||
|
this.toast.showToast('Request updated', { theme: 'success' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.goBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.mpj-recur-count {
|
||||||
|
width: 3rem;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
.mpj-recur-type {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,56 +1,90 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
span
|
article.mpj-main-content(role='main')
|
||||||
b-modal(v-model='historyVisible'
|
page-title(title='Full Prayer Request')
|
||||||
header-bg-variant='mpj'
|
template(v-if='request')
|
||||||
header-text-variant='light'
|
p
|
||||||
size='lg'
|
span(v-if='isAnswered') Answered {{ formatDate(answered) }} (#[date-from-now(:value='answered')])
|
||||||
title='Prayer Request History'
|
small: em.mpj-muted-text prayed {{ prayedCount }} times, open {{ openDays }} days
|
||||||
@shows='focusRequestText')
|
p.mpj-request-text {{ lastText }}
|
||||||
b-list-group(v-if='null !== full'
|
br
|
||||||
flush)
|
table.mpj-request-log
|
||||||
full-request-history(v-for='item in full.history'
|
thead
|
||||||
:key='item.asOf'
|
tr
|
||||||
:history='item')
|
th Action
|
||||||
div.w-100.text-right(slot='modal-footer')
|
th Update / Notes
|
||||||
b-btn(variant='primary'
|
tbody
|
||||||
@click='closeDialog()') Close
|
tr(v-for='item in log' :key='item.asOf')
|
||||||
|
td {{ item.status }} on #[span.mpj-text-nowrap {{ formatDate(item.asOf) }}]
|
||||||
|
td(v-if='item.text').mpj-request-text {{ item.text.fields[0] }}
|
||||||
|
td(v-else)
|
||||||
|
p(v-else) Loading request...
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import FullRequestHistory from './FullRequestHistory'
|
import moment from 'moment'
|
||||||
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
|
||||||
|
const asOfDesc = (a, b) => b.asOf - a.asOf
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'full-request',
|
name: 'full-request',
|
||||||
components: {
|
|
||||||
FullRequestHistory
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
events: { required: true }
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
historyVisible: false,
|
request: null
|
||||||
full: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
computed: {
|
||||||
this.events.$on('full', this.openDialog)
|
answered () {
|
||||||
|
return this.request.history.find(hist => hist.status === 'Answered').asOf
|
||||||
|
},
|
||||||
|
isAnswered () {
|
||||||
|
return this.request.history.filter(hist => hist.status === 'Answered').length > 0
|
||||||
|
},
|
||||||
|
lastText () {
|
||||||
|
return this.request.history
|
||||||
|
.filter(hist => hist.text)
|
||||||
|
.sort(asOfDesc)[0].text.fields[0]
|
||||||
|
},
|
||||||
|
log () {
|
||||||
|
const allHistory = (this.request.notes || [])
|
||||||
|
.map(note => ({ asOf: note.asOf, text: { case: 'Some', fields: [ note.notes ] }, status: 'Notes' }))
|
||||||
|
.concat(this.request.history)
|
||||||
|
.sort(asOfDesc)
|
||||||
|
// Skip the first entry for answered requests; that info is already displayed
|
||||||
|
return this.isAnswered ? allHistory.slice(1) : allHistory
|
||||||
|
},
|
||||||
|
openDays () {
|
||||||
|
const asOf = this.isAnswered ? this.answered : Date.now()
|
||||||
|
return Math.floor(
|
||||||
|
(asOf - this.request.history.find(hist => hist.status === 'Created').asOf) / 1000 / 60 / 60 / 24)
|
||||||
|
},
|
||||||
|
prayedCount () {
|
||||||
|
return this.request.history.filter(hist => hist.status === 'Prayed').length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted () {
|
||||||
|
this.$Progress.start()
|
||||||
|
try {
|
||||||
|
const req = await api.getFullRequest(this.id)
|
||||||
|
this.request = req.data
|
||||||
|
this.$Progress.finish()
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
this.$Progress.fail()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeDialog () {
|
formatDate (asOf) {
|
||||||
this.full = null
|
return moment(asOf).format('LL')
|
||||||
this.historyVisible = false
|
|
||||||
},
|
|
||||||
async openDialog (requestId) {
|
|
||||||
this.historyVisible = true
|
|
||||||
this.$Progress.start()
|
|
||||||
const req = await api.getFullRequest(requestId)
|
|
||||||
this.full = req.data
|
|
||||||
this.$Progress.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<template lang="pug">
|
|
||||||
b-list-group-item
|
|
||||||
| {{ history.status }}
|
|
||||||
|
|
|
||||||
small.text-muted(:title='actualDate') {{ asOf }}
|
|
||||||
div(v-if='history.text').mpj-request-text {{ history.text.fields[0] }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
import moment from 'moment'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'full-request-history',
|
|
||||||
props: {
|
|
||||||
history: { required: true }
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
asOf () {
|
|
||||||
return moment(this.history.asOf).fromNow()
|
|
||||||
},
|
|
||||||
actualDate () {
|
|
||||||
return moment(this.history.asOf).format('LLLL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,71 +0,0 @@
|
||||||
<template lang="pug">
|
|
||||||
div
|
|
||||||
b-btn(@click='openDialog()' size='sm' variant='primary')
|
|
||||||
icon(name='plus')
|
|
||||||
| Add a New Request
|
|
||||||
b-modal(v-model='showNewVisible'
|
|
||||||
header-bg-variant='mpj'
|
|
||||||
header-text-variant='light'
|
|
||||||
size='lg'
|
|
||||||
title='Add a New Prayer Request'
|
|
||||||
@shown='focusRequestText')
|
|
||||||
b-form
|
|
||||||
b-form-group(label='Prayer Request'
|
|
||||||
label-for='request_text')
|
|
||||||
b-textarea#request_text(ref='toFocus'
|
|
||||||
v-model='form.requestText'
|
|
||||||
:rows='10'
|
|
||||||
@blur='trimText()')
|
|
||||||
div.w-100.text-right(slot='modal-footer')
|
|
||||||
b-btn(variant='primary'
|
|
||||||
@click='saveRequest()') Save
|
|
||||||
|
|
|
||||||
b-btn(variant='outline-secondary'
|
|
||||||
@click='closeDialog()') Cancel
|
|
||||||
toast(ref='toast')
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'new-request',
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
showNewVisible: false,
|
|
||||||
form: {
|
|
||||||
requestText: ''
|
|
||||||
},
|
|
||||||
formLabelWidth: '120px'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
this.$refs.toast.setOptions({ position: 'bottom right' })
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
closeDialog () {
|
|
||||||
this.form.requestText = ''
|
|
||||||
this.showNewVisible = false
|
|
||||||
},
|
|
||||||
focusRequestText (e) {
|
|
||||||
this.$refs.toFocus.focus()
|
|
||||||
},
|
|
||||||
openDialog () {
|
|
||||||
this.showNewVisible = true
|
|
||||||
},
|
|
||||||
trimText () {
|
|
||||||
this.form.requestText = this.form.requestText.trim()
|
|
||||||
},
|
|
||||||
async saveRequest () {
|
|
||||||
await this.$store.dispatch(actions.ADD_REQUEST, {
|
|
||||||
progress: this.$Progress,
|
|
||||||
requestText: this.form.requestText
|
|
||||||
})
|
|
||||||
this.$refs.toast.showToast('New prayer request added', { theme: 'success' })
|
|
||||||
this.closeDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,36 +1,33 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
b-modal(v-model='notesVisible'
|
.mpj-modal(v-show='notesVisible')
|
||||||
header-bg-variant='mpj'
|
.mpj-modal-content.mpj-narrow
|
||||||
header-text-variant='light'
|
header.mpj-bg
|
||||||
size='lg'
|
h5 Add Notes to Prayer Request
|
||||||
title='Add Notes to Prayer Request'
|
label
|
||||||
@edit='openDialog()'
|
| Notes
|
||||||
@shows='focusNotes')
|
br
|
||||||
b-form
|
textarea(v-model='form.notes'
|
||||||
b-form-group(label='Notes'
|
:rows='10'
|
||||||
label-for='notes')
|
@blur='trimText()').mpj-full-width
|
||||||
b-textarea#notes(ref='toFocus'
|
.mpj-text-right
|
||||||
v-model='form.notes'
|
button(@click='saveNotes()').primary.
|
||||||
:rows='10'
|
#[md-icon(icon='save')] Save
|
||||||
@blur='trimText()')
|
|
|
||||||
div(v-if='hasPriorNotes')
|
button(@click='closeDialog()').
|
||||||
p.text-center: strong Prior Notes for This Request
|
#[md-icon(icon='undo')] Cancel
|
||||||
b-list-group(flush)
|
hr
|
||||||
b-list-group-item(v-for='note in priorNotes'
|
div(v-if='hasPriorNotes')
|
||||||
:key='note.asOf')
|
p.mpj-text-center: strong Prior Notes for This Request
|
||||||
small.text-muted: date-from-now(:value='note.asOf')
|
.mpj-note-list
|
||||||
br
|
p(v-for='note in priorNotes'
|
||||||
div.mpj-request-text {{ note.notes }}
|
:key='note.asOf')
|
||||||
div(v-else-if='noPriorNotes').text-center.text-muted There are no prior notes for this request
|
small.mpj-muted-text: date-from-now(:value='note.asOf')
|
||||||
div(v-else).text-center
|
br
|
||||||
b-btn(variant='outline-secondary'
|
span.mpj-request-text {{ note.notes }}
|
||||||
@click='loadNotes()') Load Prior Notes
|
div(v-else-if='noPriorNotes').mpj-text-center.mpj-muted-text There are no prior notes for this request
|
||||||
div.w-100.text-right(slot='modal-footer')
|
div(v-else).mpj-text-center
|
||||||
b-btn(variant='primary'
|
button(@click='loadNotes()').
|
||||||
@click='saveNotes()') Save
|
#[md-icon(icon='cloud_download')] Load Prior Notes
|
||||||
|
|
|
||||||
b-btn(variant='outline-secondary'
|
|
||||||
@click='closeDialog()') Cancel
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -74,15 +71,11 @@ export default {
|
||||||
this.priorNotesLoaded = false
|
this.priorNotesLoaded = false
|
||||||
this.notesVisible = false
|
this.notesVisible = false
|
||||||
},
|
},
|
||||||
focusNotes (e) {
|
|
||||||
this.$refs.toFocus.focus()
|
|
||||||
},
|
|
||||||
async loadNotes () {
|
async loadNotes () {
|
||||||
this.$Progress.start()
|
this.$Progress.start()
|
||||||
try {
|
try {
|
||||||
const notes = await api.getNotes(this.form.requestId)
|
const notes = await api.getNotes(this.form.requestId)
|
||||||
this.priorNotes = notes.data
|
this.priorNotes = notes.data
|
||||||
console.log(this.priorNotes)
|
|
||||||
this.$Progress.finish()
|
this.$Progress.finish()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
@ -94,7 +87,6 @@ export default {
|
||||||
openDialog (request) {
|
openDialog (request) {
|
||||||
this.form.requestId = request.requestId
|
this.form.requestId = request.requestId
|
||||||
this.notesVisible = true
|
this.notesVisible = true
|
||||||
this.focusNotes(null)
|
|
||||||
},
|
},
|
||||||
async saveNotes () {
|
async saveNotes () {
|
||||||
this.$Progress.start()
|
this.$Progress.start()
|
||||||
|
@ -114,3 +106,9 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.mpj-note-list p {
|
||||||
|
border-top: dotted 1px lightgray;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
b-col(v-if="!isSnoozed" md='6' lg='4')
|
.mpj-request-card(v-if='shouldDisplay')
|
||||||
.mpj-request-card
|
header.mpj-card-header(role='toolbar').
|
||||||
b-card-header.text-center.py-1.
|
#[button(@click='markPrayed()' title='Pray').primary: md-icon(icon='done')]
|
||||||
#[b-btn(@click='markPrayed()' variant='outline-primary' title='Pray' size='sm'): icon(name='check')]
|
#[button(@click.stop='showEdit()' title='Edit'): md-icon(icon='edit')]
|
||||||
#[b-btn(@click.stop='showEdit()' variant='outline-secondary' title='Edit' size='sm'): icon(name='pencil')]
|
#[button(@click.stop='showNotes()' title='Add Notes'): md-icon(icon='comment')]
|
||||||
#[b-btn(@click.stop='showNotes()' variant='outline-secondary' title='Add Notes' size='sm'): icon(name='file-text-o')]
|
#[button(@click.stop='snooze()' title='Snooze Request'): md-icon(icon='schedule')]
|
||||||
#[b-btn(@click.stop='showFull()' variant='outline-secondary' title='View Full Request' size='sm'): icon(name='search')]
|
div
|
||||||
#[b-btn(@click.stop='snooze()' variant='outline-secondary' title='Snooze Request' size='sm'): icon(name='clock-o')]
|
p.card-text.mpj-request-text
|
||||||
b-card-body.p-0
|
| {{ request.text }}
|
||||||
p.card-text.mpj-request-text.mb-1.px-3.pt-3
|
p.as-of.mpj-text-right: small.mpj-muted-text: em
|
||||||
| {{ request.text }}
|
= '(last activity '
|
||||||
p.card-text.p-0.pr-1.text-right: small.text-muted: em
|
date-from-now(:value='request.asOf')
|
||||||
= '(last activity '
|
| )
|
||||||
date-from-now(:value='request.asOf')
|
|
||||||
| )
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -29,8 +27,9 @@ export default {
|
||||||
events: { required: true }
|
events: { required: true }
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isSnoozed () {
|
shouldDisplay () {
|
||||||
return Date.now() < this.request.snoozedUntil
|
const now = Date.now()
|
||||||
|
return Math.max(now, this.request.showAfter, this.request.snoozedUntil) === now
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -44,10 +43,7 @@ export default {
|
||||||
this.toast.showToast('Request marked as prayed', { theme: 'success' })
|
this.toast.showToast('Request marked as prayed', { theme: 'success' })
|
||||||
},
|
},
|
||||||
showEdit () {
|
showEdit () {
|
||||||
this.events.$emit('edit', this.request)
|
this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
|
||||||
},
|
|
||||||
showFull () {
|
|
||||||
this.events.$emit('full', this.request.requestId)
|
|
||||||
},
|
},
|
||||||
showNotes () {
|
showNotes () {
|
||||||
this.events.$emit('notes', this.request)
|
this.events.$emit('notes', this.request)
|
||||||
|
@ -63,6 +59,35 @@ export default {
|
||||||
.mpj-request-card {
|
.mpj-request-card {
|
||||||
border: solid 1px darkgray;
|
border: solid 1px darkgray;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
margin-bottom: 15px;
|
width: 20rem;
|
||||||
|
margin: .5rem;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 20rem) {
|
||||||
|
.mpj-request-card {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mpj-card-header {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row;
|
||||||
|
justify-content: center;
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(lightgray), to(whitesmoke));
|
||||||
|
background-image: -webkit-linear-gradient(top, lightgray, whitesmoke);
|
||||||
|
background-image: -moz-linear-gradient(top, lightgray, whitesmoke);
|
||||||
|
background-image: linear-gradient(to bottom, lightgray, whitesmoke);
|
||||||
|
}
|
||||||
|
.mpj-card-header button {
|
||||||
|
margin: .25rem;
|
||||||
|
padding: 0 .25rem;
|
||||||
|
}
|
||||||
|
.mpj-card-header button .material-icons {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
.mpj-request-card .card-text {
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
.mpj-request-card .as-of {
|
||||||
|
margin-right: .25rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
86
src/app/src/components/request/RequestListItem.vue
Normal file
86
src/app/src/components/request/RequestListItem.vue
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<template lang="pug">
|
||||||
|
p.mpj-request-text
|
||||||
|
| {{ request.text }}
|
||||||
|
br
|
||||||
|
br
|
||||||
|
button(@click='viewFull'
|
||||||
|
title='View Full Request').
|
||||||
|
#[md-icon(icon='description')] View Full Request
|
||||||
|
|
|
||||||
|
template(v-if='!isAnswered')
|
||||||
|
button(@click='editRequest'
|
||||||
|
title='Edit Request').
|
||||||
|
#[md-icon(icon='edit')] Edit Request
|
||||||
|
|
|
||||||
|
template(v-if='isSnoozed')
|
||||||
|
button(@click='cancelSnooze()').
|
||||||
|
#[md-icon(icon='restore')] Cancel Snooze
|
||||||
|
|
|
||||||
|
template(v-if='isPending')
|
||||||
|
button(@click='showNow()').
|
||||||
|
#[md-icon(icon='restore')] Show Now
|
||||||
|
br(v-if='isSnoozed || isPending || isAnswered')
|
||||||
|
small(v-if='isSnoozed').mpj-muted-text: em.
|
||||||
|
Snooze expires #[date-from-now(:value='request.snoozedUntil')]
|
||||||
|
small(v-if='isPending').mpj-muted-text: em.
|
||||||
|
Request scheduled to reappear #[date-from-now(:value='request.showAfter')]
|
||||||
|
small(v-if='isAnswered').mpj-muted-text: em.
|
||||||
|
Answered #[date-from-now(:value='request.asOf')]
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
import actions from '@/store/action-types'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'request-list-item',
|
||||||
|
props: {
|
||||||
|
request: { required: true },
|
||||||
|
toast: { required: true }
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
answered () {
|
||||||
|
return this.request.history.find(hist => hist.status === 'Answered').asOf
|
||||||
|
},
|
||||||
|
isAnswered () {
|
||||||
|
return this.request.lastStatus === 'Answered'
|
||||||
|
},
|
||||||
|
isPending () {
|
||||||
|
return !this.isSnoozed && this.request.showAfter > Date.now()
|
||||||
|
},
|
||||||
|
isSnoozed () {
|
||||||
|
return this.request.snoozedUntil > Date.now()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async cancelSnooze () {
|
||||||
|
await this.$store.dispatch(actions.SNOOZE_REQUEST, {
|
||||||
|
progress: this.$Progress,
|
||||||
|
requestId: this.request.requestId,
|
||||||
|
until: 0
|
||||||
|
})
|
||||||
|
this.toast.showToast('Request un-snoozed', { theme: 'success' })
|
||||||
|
this.$parent.$emit('requestUnsnoozed')
|
||||||
|
},
|
||||||
|
editRequest () {
|
||||||
|
this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
|
||||||
|
},
|
||||||
|
async showNow () {
|
||||||
|
await this.$store.dispatch(actions.SHOW_REQUEST_NOW, {
|
||||||
|
progress: this.$Progress,
|
||||||
|
requestId: this.request.requestId,
|
||||||
|
showAfter: Date.now()
|
||||||
|
})
|
||||||
|
this.toast.showToast('Recurrence skipped; request now shows in journal', { theme: 'success' })
|
||||||
|
this.$parent.$emit('requestNowShown')
|
||||||
|
},
|
||||||
|
viewFull () {
|
||||||
|
this.$router.push({ name: 'FullRequest', params: { id: this.request.requestId } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,23 +1,22 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
b-modal(v-model='snoozeVisible'
|
.mpj-modal(v-show='snoozeVisible')
|
||||||
header-bg-variant='mpj'
|
.mpj-modal-content.mpj-skinny
|
||||||
header-text-variant='light'
|
header.mpj-bg
|
||||||
size='lg'
|
h5 Snooze Prayer Request
|
||||||
title='Snooze Prayer Request'
|
p.mpj-text-center
|
||||||
@edit='openDialog()')
|
label
|
||||||
b-form
|
= 'Until '
|
||||||
b-form-group(label='Until'
|
input(v-model='form.snoozedUntil'
|
||||||
label-for='until')
|
type='date'
|
||||||
b-input#until(type='date'
|
autofocus)
|
||||||
v-model='form.snoozedUntil'
|
br
|
||||||
autofocus)
|
.mpj-text-right
|
||||||
div.w-100.text-right(slot='modal-footer')
|
button.primary(:disabled='!isValid'
|
||||||
b-btn(variant='primary'
|
@click='snoozeRequest()').
|
||||||
:disabled='!isValid'
|
#[md-icon(icon='snooze')] Snooze
|
||||||
@click='snoozeRequest()') Snooze
|
|
|
||||||
|
|
button(@click='closeDialog()').
|
||||||
b-btn(variant='outline-secondary'
|
#[md-icon(icon='undo')] Cancel
|
||||||
@click='closeDialog()') Cancel
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
59
src/app/src/components/request/SnoozedRequests.vue
Normal file
59
src/app/src/components/request/SnoozedRequests.vue
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<template lang="pug">
|
||||||
|
article.mpj-main-content(role='main')
|
||||||
|
page-title(title='Snoozed Requests')
|
||||||
|
div(v-if='loaded').mpj-request-list
|
||||||
|
p.mpj-text-center(v-if='requests.length === 0'): em.
|
||||||
|
No snoozed requests found; return to #[router-link(:to='{ name: "Journal" } ') your journal]
|
||||||
|
request-list-item(v-for='req in requests'
|
||||||
|
:key='req.requestId'
|
||||||
|
:request='req'
|
||||||
|
:toast='toast')
|
||||||
|
p(v-else) Loading journal...
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
|
import actions from '@/store/action-types'
|
||||||
|
|
||||||
|
import RequestListItem from '@/components/request/RequestListItem'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'snoozed-requests',
|
||||||
|
components: {
|
||||||
|
RequestListItem
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
requests: [],
|
||||||
|
loaded: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
toast () {
|
||||||
|
return this.$parent.$refs.toast
|
||||||
|
},
|
||||||
|
...mapState(['journal', 'isLoadingJournal'])
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.$on('requestUnsnoozed', this.ensureJournal)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async ensureJournal () {
|
||||||
|
if (!Array.isArray(this.journal)) {
|
||||||
|
this.loaded = false
|
||||||
|
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
||||||
|
}
|
||||||
|
this.requests = this.journal
|
||||||
|
.filter(req => req.snoozedUntil > Date.now())
|
||||||
|
.sort((a, b) => a.snoozedUntil - b.snoozedUntil)
|
||||||
|
this.loaded = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted () {
|
||||||
|
await this.ensureJournal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,5 +1,5 @@
|
||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
article
|
article.mpj-main-content(role='main')
|
||||||
pageTitle(title='Logging On')
|
pageTitle(title='Logging On')
|
||||||
p Logging you on...
|
p Logging you on...
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,31 +1,18 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import BootstrapVue from 'bootstrap-vue'
|
|
||||||
import Icon from 'vue-awesome/components/Icon'
|
|
||||||
import VueProgressBar from 'vue-progressbar'
|
import VueProgressBar from 'vue-progressbar'
|
||||||
import VueToast from 'vue-toast'
|
import VueToast from 'vue-toast'
|
||||||
|
|
||||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
|
||||||
import 'bootstrap/dist/css/bootstrap.css'
|
|
||||||
import 'vue-toast/dist/vue-toast.min.css'
|
import 'vue-toast/dist/vue-toast.min.css'
|
||||||
|
|
||||||
// Only import the icons we need; the whole set is ~500K!
|
import App from './App'
|
||||||
import 'vue-awesome/icons/check'
|
|
||||||
import 'vue-awesome/icons/clock-o'
|
|
||||||
import 'vue-awesome/icons/file-text-o'
|
|
||||||
import 'vue-awesome/icons/pencil'
|
|
||||||
import 'vue-awesome/icons/plus'
|
|
||||||
import 'vue-awesome/icons/search'
|
|
||||||
import 'vue-awesome/icons/times'
|
|
||||||
|
|
||||||
import App from './App.vue'
|
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import DateFromNow from './components/common/DateFromNow'
|
import DateFromNow from './components/common/DateFromNow'
|
||||||
|
import MaterialDesignIcon from './components/common/MaterialDesignIcon'
|
||||||
import PageTitle from './components/common/PageTitle'
|
import PageTitle from './components/common/PageTitle'
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
Vue.use(BootstrapVue)
|
|
||||||
Vue.use(VueProgressBar, {
|
Vue.use(VueProgressBar, {
|
||||||
color: 'yellow',
|
color: 'yellow',
|
||||||
failedColor: 'red',
|
failedColor: 'red',
|
||||||
|
@ -37,8 +24,8 @@ Vue.use(VueProgressBar, {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Vue.component('icon', Icon)
|
|
||||||
Vue.component('date-from-now', DateFromNow)
|
Vue.component('date-from-now', DateFromNow)
|
||||||
|
Vue.component('md-icon', MaterialDesignIcon)
|
||||||
Vue.component('page-title', PageTitle)
|
Vue.component('page-title', PageTitle)
|
||||||
Vue.component('toast', VueToast)
|
Vue.component('toast', VueToast)
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Router from 'vue-router'
|
import Router from 'vue-router'
|
||||||
|
|
||||||
import Answered from '@/components/Answered'
|
import ActiveRequests from '@/components/request/ActiveRequests'
|
||||||
import AnsweredDetail from '@/components/AnsweredDetail'
|
import AnsweredRequests from '@/components/request/AnsweredRequests'
|
||||||
|
import EditRequest from '@/components/request/EditRequest'
|
||||||
|
import FullRequest from '@/components/request/FullRequest'
|
||||||
import Home from '@/components/Home'
|
import Home from '@/components/Home'
|
||||||
import Journal from '@/components/Journal'
|
import Journal from '@/components/Journal'
|
||||||
import LogOn from '@/components/user/LogOn'
|
import LogOn from '@/components/user/LogOn'
|
||||||
import PrivacyPolicy from '@/components/legal/PrivacyPolicy'
|
import PrivacyPolicy from '@/components/legal/PrivacyPolicy'
|
||||||
import Snoozed from '@/components/Snoozed'
|
import SnoozedRequests from '@/components/request/SnoozedRequests'
|
||||||
import TermsOfService from '@/components/legal/TermsOfService'
|
import TermsOfService from '@/components/legal/TermsOfService'
|
||||||
|
|
||||||
Vue.use(Router)
|
Vue.use(Router)
|
||||||
|
@ -15,23 +19,19 @@ Vue.use(Router)
|
||||||
export default new Router({
|
export default new Router({
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
base: process.env.BASE_URL,
|
base: process.env.BASE_URL,
|
||||||
|
scrollBehavior (to, from, savedPosition) {
|
||||||
|
if (savedPosition) {
|
||||||
|
return savedPosition
|
||||||
|
} else {
|
||||||
|
return { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
component: Home
|
component: Home
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/answered/:id',
|
|
||||||
name: 'AnsweredDetail',
|
|
||||||
component: AnsweredDetail,
|
|
||||||
props: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/answered',
|
|
||||||
name: 'Answered',
|
|
||||||
component: Answered
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/journal',
|
path: '/journal',
|
||||||
name: 'Journal',
|
name: 'Journal',
|
||||||
|
@ -48,9 +48,31 @@ export default new Router({
|
||||||
component: TermsOfService
|
component: TermsOfService
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/snoozed',
|
path: '/request/:id/edit',
|
||||||
name: 'Snoozed',
|
name: 'EditRequest',
|
||||||
component: Snoozed
|
component: EditRequest,
|
||||||
|
props: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/request/:id/full',
|
||||||
|
name: 'FullRequest',
|
||||||
|
component: FullRequest,
|
||||||
|
props: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/requests/active',
|
||||||
|
name: 'ActiveRequests',
|
||||||
|
component: ActiveRequests
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/requests/answered',
|
||||||
|
name: 'AnsweredRequests',
|
||||||
|
component: AnsweredRequests
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/requests/snoozed',
|
||||||
|
name: 'SnoozedRequests',
|
||||||
|
component: SnoozedRequests
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/user/log-on',
|
path: '/user/log-on',
|
||||||
|
|
|
@ -7,6 +7,8 @@ export default {
|
||||||
LOAD_JOURNAL: 'load-journal',
|
LOAD_JOURNAL: 'load-journal',
|
||||||
/** Action to update a request */
|
/** Action to update a request */
|
||||||
UPDATE_REQUEST: 'update-request',
|
UPDATE_REQUEST: 'update-request',
|
||||||
|
/** Action to skip the remaining recurrence period */
|
||||||
|
SHOW_REQUEST_NOW: 'show-request-now',
|
||||||
/** Action to snooze a request */
|
/** Action to snooze a request */
|
||||||
SNOOZE_REQUEST: 'snooze-request'
|
SNOOZE_REQUEST: 'snooze-request'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
@ -71,10 +73,10 @@ export default new Vuex.Store({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async [actions.ADD_REQUEST] ({ commit }, { progress, requestText }) {
|
async [actions.ADD_REQUEST] ({ commit }, { progress, requestText, recurType, recurCount }) {
|
||||||
progress.start()
|
progress.start()
|
||||||
try {
|
try {
|
||||||
const newRequest = await api.addRequest(requestText)
|
const newRequest = await api.addRequest(requestText, recurType, recurCount)
|
||||||
commit(mutations.REQUEST_ADDED, newRequest.data)
|
commit(mutations.REQUEST_ADDED, newRequest.data)
|
||||||
progress.finish()
|
progress.finish()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -98,10 +100,28 @@ export default new Vuex.Store({
|
||||||
commit(mutations.LOADING_JOURNAL, false)
|
commit(mutations.LOADING_JOURNAL, false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async [actions.UPDATE_REQUEST] ({ commit }, { progress, requestId, status, updateText }) {
|
async [actions.UPDATE_REQUEST] ({ commit, state }, { progress, requestId, status, updateText, recurType, recurCount }) {
|
||||||
progress.start()
|
progress.start()
|
||||||
try {
|
try {
|
||||||
await api.updateRequest({ requestId, status, updateText })
|
let oldReq = (state.journal.filter(req => req.requestId === requestId) || [])[0] || {}
|
||||||
|
if (status !== 'Updated' || oldReq.text !== updateText) {
|
||||||
|
await api.updateRequest(requestId, status, updateText)
|
||||||
|
}
|
||||||
|
if (status === 'Updated' && (oldReq.recurType !== recurType || oldReq.recurCount !== recurCount)) {
|
||||||
|
await api.updateRecurrence(requestId, recurType, recurCount)
|
||||||
|
}
|
||||||
|
const request = await api.getRequest(requestId)
|
||||||
|
commit(mutations.REQUEST_UPDATED, request.data)
|
||||||
|
progress.finish()
|
||||||
|
} catch (err) {
|
||||||
|
logError(err)
|
||||||
|
progress.fail()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async [actions.SHOW_REQUEST_NOW] ({ commit }, { progress, requestId, showAfter }) {
|
||||||
|
progress.start()
|
||||||
|
try {
|
||||||
|
await api.showRequest(requestId, showAfter)
|
||||||
const request = await api.getRequest(requestId)
|
const request = await api.getRequest(requestId)
|
||||||
commit(mutations.REQUEST_UPDATED, request.data)
|
commit(mutations.REQUEST_UPDATED, request.data)
|
||||||
progress.finish()
|
progress.finish()
|
||||||
|
|
|
@ -663,9 +663,9 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/babel-types" "*"
|
"@types/babel-types" "*"
|
||||||
|
|
||||||
"@vue/babel-preset-app@^3.0.0":
|
"@vue/babel-preset-app@^3.0.1":
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-3.0.0.tgz#56bbd624eb78fa1d5f7bf992ac62e6fc7557bd71"
|
resolved "https://registry.yarnpkg.com/@vue/babel-preset-app/-/babel-preset-app-3.0.1.tgz#24188938e93f259f7141a6a1190da9c511d123d8"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/plugin-proposal-class-properties" "7.0.0-beta.47"
|
"@babel/plugin-proposal-class-properties" "7.0.0-beta.47"
|
||||||
"@babel/plugin-proposal-decorators" "7.0.0-beta.47"
|
"@babel/plugin-proposal-decorators" "7.0.0-beta.47"
|
||||||
|
@ -679,34 +679,34 @@
|
||||||
babel-plugin-transform-vue-jsx "^4.0.1"
|
babel-plugin-transform-vue-jsx "^4.0.1"
|
||||||
|
|
||||||
"@vue/cli-overlay@^3.0.0":
|
"@vue/cli-overlay@^3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-3.0.0.tgz#580340afde2cf155b71c67907f27a69b906416b6"
|
resolved "https://registry.yarnpkg.com/@vue/cli-overlay/-/cli-overlay-3.0.1.tgz#474067e18fc7c1b303c97901175d6441bfdcde6f"
|
||||||
|
|
||||||
"@vue/cli-plugin-babel@^3.0.0":
|
"@vue/cli-plugin-babel@^3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-3.0.0.tgz#5e3e2ae3435929b26994250692fa7a20e5cd6883"
|
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-babel/-/cli-plugin-babel-3.0.1.tgz#a1691caf610d42800314ceb9e727a7668bfa3e7f"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/core" "7.0.0-beta.47"
|
"@babel/core" "7.0.0-beta.47"
|
||||||
"@vue/babel-preset-app" "^3.0.0"
|
"@vue/babel-preset-app" "^3.0.1"
|
||||||
babel-loader "^8.0.0-0"
|
babel-loader "^8.0.0-0"
|
||||||
|
|
||||||
"@vue/cli-plugin-eslint@^3.0.0":
|
"@vue/cli-plugin-eslint@^3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-3.0.0.tgz#97b163df1272b39e61e18c8add5dfe28a92375c4"
|
resolved "https://registry.yarnpkg.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-3.0.1.tgz#9330cfe4843058f28b0ab2871a8862fa31f3a5c0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/cli-shared-utils" "^3.0.0"
|
"@vue/cli-shared-utils" "^3.0.1"
|
||||||
babel-eslint "^8.2.5"
|
babel-eslint "^8.2.5"
|
||||||
eslint "^4.19.1"
|
eslint "^4.19.1"
|
||||||
eslint-loader "^2.0.0"
|
eslint-loader "^2.0.0"
|
||||||
eslint-plugin-vue "^4.5.0"
|
eslint-plugin-vue "^4.5.0"
|
||||||
|
|
||||||
"@vue/cli-service@^3.0.0":
|
"@vue/cli-service@^3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-3.0.0.tgz#c808a846072dcf5751aad786439f53fc0a812bf4"
|
resolved "https://registry.yarnpkg.com/@vue/cli-service/-/cli-service-3.0.1.tgz#086c4b3b78bda7b0f4e1e7324237c62c89c5e6b3"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@intervolga/optimize-cssnano-plugin" "^1.0.5"
|
"@intervolga/optimize-cssnano-plugin" "^1.0.5"
|
||||||
"@vue/cli-overlay" "^3.0.0"
|
"@vue/cli-overlay" "^3.0.0"
|
||||||
"@vue/cli-shared-utils" "^3.0.0"
|
"@vue/cli-shared-utils" "^3.0.1"
|
||||||
"@vue/preload-webpack-plugin" "^1.1.0"
|
"@vue/preload-webpack-plugin" "^1.1.0"
|
||||||
"@vue/web-component-wrapper" "^1.2.0"
|
"@vue/web-component-wrapper" "^1.2.0"
|
||||||
acorn "^5.7.1"
|
acorn "^5.7.1"
|
||||||
|
@ -719,6 +719,7 @@
|
||||||
cliui "^4.1.0"
|
cliui "^4.1.0"
|
||||||
copy-webpack-plugin "^4.5.2"
|
copy-webpack-plugin "^4.5.2"
|
||||||
css-loader "^1.0.0"
|
css-loader "^1.0.0"
|
||||||
|
cssnano "^4.0.0"
|
||||||
debug "^3.1.0"
|
debug "^3.1.0"
|
||||||
escape-string-regexp "^1.0.5"
|
escape-string-regexp "^1.0.5"
|
||||||
file-loader "^1.1.11"
|
file-loader "^1.1.11"
|
||||||
|
@ -744,7 +745,7 @@
|
||||||
string.prototype.padend "^3.0.0"
|
string.prototype.padend "^3.0.0"
|
||||||
thread-loader "^1.1.5"
|
thread-loader "^1.1.5"
|
||||||
uglifyjs-webpack-plugin "^1.2.7"
|
uglifyjs-webpack-plugin "^1.2.7"
|
||||||
url-loader "^1.0.1"
|
url-loader "^1.1.0"
|
||||||
vue-loader "^15.3.0"
|
vue-loader "^15.3.0"
|
||||||
webpack "^4.15.1"
|
webpack "^4.15.1"
|
||||||
webpack-bundle-analyzer "^2.13.1"
|
webpack-bundle-analyzer "^2.13.1"
|
||||||
|
@ -753,9 +754,9 @@
|
||||||
webpack-merge "^4.1.3"
|
webpack-merge "^4.1.3"
|
||||||
yorkie "^2.0.0"
|
yorkie "^2.0.0"
|
||||||
|
|
||||||
"@vue/cli-shared-utils@^3.0.0":
|
"@vue/cli-shared-utils@^3.0.1":
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-3.0.0.tgz#f4886ce9a62dd2088e112af4d54f61c1667318d0"
|
resolved "https://registry.yarnpkg.com/@vue/cli-shared-utils/-/cli-shared-utils-3.0.1.tgz#1084f8e4c20a01b3bb17059992aedc6d4774e270"
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk "^2.4.1"
|
chalk "^2.4.1"
|
||||||
execa "^0.10.0"
|
execa "^0.10.0"
|
||||||
|
@ -770,8 +771,8 @@
|
||||||
string.prototype.padstart "^3.0.0"
|
string.prototype.padstart "^3.0.0"
|
||||||
|
|
||||||
"@vue/component-compiler-utils@^2.0.0":
|
"@vue/component-compiler-utils@^2.0.0":
|
||||||
version "2.1.2"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.1.2.tgz#75e7cc8496baecbb0994dc8783571d9ff07737fe"
|
resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.2.0.tgz#bbbb7ed38a9a8a7c93abe7ef2e54a90a04b631b4"
|
||||||
dependencies:
|
dependencies:
|
||||||
consolidate "^0.15.1"
|
consolidate "^0.15.1"
|
||||||
hash-sum "^1.0.2"
|
hash-sum "^1.0.2"
|
||||||
|
@ -784,8 +785,8 @@
|
||||||
vue-template-es2015-compiler "^1.6.0"
|
vue-template-es2015-compiler "^1.6.0"
|
||||||
|
|
||||||
"@vue/eslint-config-standard@^3.0.0":
|
"@vue/eslint-config-standard@^3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/eslint-config-standard/-/eslint-config-standard-3.0.0.tgz#2a995fa4fac38bbb0947c8bceb4144eabf62df6a"
|
resolved "https://registry.yarnpkg.com/@vue/eslint-config-standard/-/eslint-config-standard-3.0.1.tgz#34f322c857ee525aa6d0edda83b2b1698278b682"
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-config-standard "^12.0.0-alpha.0"
|
eslint-config-standard "^12.0.0-alpha.0"
|
||||||
eslint-plugin-import "^2.11.0"
|
eslint-plugin-import "^2.11.0"
|
||||||
|
@ -993,6 +994,10 @@ address@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
|
resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
|
||||||
|
|
||||||
|
ajv-errors@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59"
|
||||||
|
|
||||||
ajv-keywords@^2.1.0:
|
ajv-keywords@^2.1.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
|
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
|
||||||
|
@ -1011,13 +1016,13 @@ ajv@^5.2.3, ajv@^5.3.0:
|
||||||
json-schema-traverse "^0.3.0"
|
json-schema-traverse "^0.3.0"
|
||||||
|
|
||||||
ajv@^6.1.0:
|
ajv@^6.1.0:
|
||||||
version "6.5.2"
|
version "6.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360"
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal "^2.0.1"
|
fast-deep-equal "^2.0.1"
|
||||||
fast-json-stable-stringify "^2.0.0"
|
fast-json-stable-stringify "^2.0.0"
|
||||||
json-schema-traverse "^0.4.1"
|
json-schema-traverse "^0.4.1"
|
||||||
uri-js "^4.2.1"
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
align-text@^0.1.1, align-text@^0.1.3:
|
align-text@^0.1.1, align-text@^0.1.3:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
|
@ -1031,10 +1036,6 @@ alphanum-sort@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
|
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
|
||||||
|
|
||||||
ansi-escapes@^1.1.0:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
|
|
||||||
|
|
||||||
ansi-escapes@^3.0.0:
|
ansi-escapes@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
|
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
|
||||||
|
@ -1215,8 +1216,8 @@ asynckit@^0.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
|
|
||||||
atob@^2.1.1:
|
atob@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a"
|
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||||
|
|
||||||
auth0-js@^9.7.3:
|
auth0-js@^9.7.3:
|
||||||
version "9.7.3"
|
version "9.7.3"
|
||||||
|
@ -1305,15 +1306,7 @@ babel-plugin-transform-vue-jsx@^4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
|
|
||||||
babel-polyfill@6.23.0:
|
babel-runtime@^6.26.0:
|
||||||
version "6.23.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d"
|
|
||||||
dependencies:
|
|
||||||
babel-runtime "^6.22.0"
|
|
||||||
core-js "^2.4.0"
|
|
||||||
regenerator-runtime "^0.10.0"
|
|
||||||
|
|
||||||
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
|
|
||||||
version "6.26.0"
|
version "6.26.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1425,21 +1418,6 @@ boolbase@^1.0.0, boolbase@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||||
|
|
||||||
bootstrap-vue@^2.0.0-rc.11:
|
|
||||||
version "2.0.0-rc.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-2.0.0-rc.11.tgz#47aaa6d2a8d390477de75e636d8ea652b1d03f59"
|
|
||||||
dependencies:
|
|
||||||
bootstrap "^4.1.1"
|
|
||||||
lodash.get "^4.4.2"
|
|
||||||
lodash.startcase "^4.4.0"
|
|
||||||
opencollective "^1.0.3"
|
|
||||||
popper.js "^1.12.9"
|
|
||||||
vue-functional-data-merge "^2.0.5"
|
|
||||||
|
|
||||||
bootstrap@^4.1.1, bootstrap@^4.1.3:
|
|
||||||
version "4.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.1.3.tgz#0eb371af2c8448e8c210411d0cb824a6409a12be"
|
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.11"
|
version "1.1.11"
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
|
@ -1665,8 +1643,8 @@ caniuse-api@^3.0.0:
|
||||||
lodash.uniq "^4.5.0"
|
lodash.uniq "^4.5.0"
|
||||||
|
|
||||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000864, caniuse-lite@^1.0.30000876:
|
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000864, caniuse-lite@^1.0.30000876:
|
||||||
version "1.0.30000876"
|
version "1.0.30000877"
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000876.tgz#69fc1b696a35fd91089061aa916f677ee7057ada"
|
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000877.tgz#f189673b86ecc06436520e3e391de6a13ca923b4"
|
||||||
|
|
||||||
case-sensitive-paths-webpack-plugin@^2.1.2:
|
case-sensitive-paths-webpack-plugin@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
|
@ -1683,7 +1661,7 @@ center-align@^0.1.1:
|
||||||
align-text "^0.1.3"
|
align-text "^0.1.3"
|
||||||
lazy-cache "^1.0.3"
|
lazy-cache "^1.0.3"
|
||||||
|
|
||||||
chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3:
|
chalk@^1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1744,9 +1722,9 @@ chrome-trace-event@^1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
ci-info@^1.0.0:
|
ci-info@^1.3.0:
|
||||||
version "1.1.3"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2"
|
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.3.1.tgz#da21bc65a5f0d0d250c19a169065532b42fa048c"
|
||||||
|
|
||||||
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
|
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
|
@ -2340,11 +2318,10 @@ defaults@^1.0.3:
|
||||||
clone "^1.0.2"
|
clone "^1.0.2"
|
||||||
|
|
||||||
define-properties@^1.1.2:
|
define-properties@^1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
|
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||||
dependencies:
|
dependencies:
|
||||||
foreach "^2.0.5"
|
object-keys "^1.0.12"
|
||||||
object-keys "^1.0.8"
|
|
||||||
|
|
||||||
define-property@^0.2.5:
|
define-property@^0.2.5:
|
||||||
version "0.2.5"
|
version "0.2.5"
|
||||||
|
@ -2555,8 +2532,8 @@ ejs@^2.5.7:
|
||||||
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
|
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
|
||||||
|
|
||||||
electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.57:
|
electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.57:
|
||||||
version "1.3.57"
|
version "1.3.58"
|
||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.57.tgz#61b2446f16af26fb8873210007a7637ad644c82d"
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.58.tgz#8267a4000014e93986d9d18c65a8b4022ca75188"
|
||||||
|
|
||||||
elliptic@^6.0.0:
|
elliptic@^6.0.0:
|
||||||
version "6.4.1"
|
version "6.4.1"
|
||||||
|
@ -2578,12 +2555,6 @@ encodeurl@~1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||||
|
|
||||||
encoding@^0.1.11:
|
|
||||||
version "0.1.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
|
|
||||||
dependencies:
|
|
||||||
iconv-lite "~0.4.13"
|
|
||||||
|
|
||||||
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
|
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
|
||||||
|
@ -2975,7 +2946,7 @@ extend@^3.0.0, extend@~3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||||
|
|
||||||
external-editor@^2.0.1, external-editor@^2.0.4:
|
external-editor@^2.0.4:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
|
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3161,13 +3132,7 @@ flush-write-stream@^1.0.0:
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
readable-stream "^2.0.4"
|
readable-stream "^2.0.4"
|
||||||
|
|
||||||
follow-redirects@^1.0.0:
|
follow-redirects@^1.0.0, follow-redirects@^1.3.0:
|
||||||
version "1.5.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.4.tgz#86d1bb946f24cb988d660aaa2ca2478c0772ead1"
|
|
||||||
dependencies:
|
|
||||||
debug "^3.1.0"
|
|
||||||
|
|
||||||
follow-redirects@^1.3.0:
|
|
||||||
version "1.5.5"
|
version "1.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.5.tgz#3c143ca599a2e22e62876687d68b23d55bad788b"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.5.tgz#3c143ca599a2e22e62876687d68b23d55bad788b"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3183,10 +3148,6 @@ for-own@^0.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
for-in "^1.0.1"
|
for-in "^1.0.1"
|
||||||
|
|
||||||
foreach@^2.0.5:
|
|
||||||
version "2.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
|
||||||
|
|
||||||
forever-agent@~0.6.1:
|
forever-agent@~0.6.1:
|
||||||
version "0.6.1"
|
version "0.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||||
|
@ -3628,7 +3589,7 @@ iconv-lite@0.4.19:
|
||||||
version "0.4.19"
|
version "0.4.19"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||||
|
|
||||||
iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
|
iconv-lite@^0.4.17, iconv-lite@^0.4.4:
|
||||||
version "0.4.23"
|
version "0.4.23"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3728,24 +3689,6 @@ ini@~1.3.0:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||||
|
|
||||||
inquirer@3.0.6:
|
|
||||||
version "3.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347"
|
|
||||||
dependencies:
|
|
||||||
ansi-escapes "^1.1.0"
|
|
||||||
chalk "^1.0.0"
|
|
||||||
cli-cursor "^2.1.0"
|
|
||||||
cli-width "^2.0.0"
|
|
||||||
external-editor "^2.0.1"
|
|
||||||
figures "^2.0.0"
|
|
||||||
lodash "^4.3.0"
|
|
||||||
mute-stream "0.0.7"
|
|
||||||
run-async "^2.2.0"
|
|
||||||
rx "^4.1.0"
|
|
||||||
string-width "^2.0.0"
|
|
||||||
strip-ansi "^3.0.0"
|
|
||||||
through "^2.3.6"
|
|
||||||
|
|
||||||
inquirer@^3.0.6:
|
inquirer@^3.0.6:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
|
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
|
||||||
|
@ -3834,10 +3777,10 @@ is-callable@^1.1.1, is-callable@^1.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
|
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
|
||||||
|
|
||||||
is-ci@^1.0.10:
|
is-ci@^1.0.10:
|
||||||
version "1.1.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5"
|
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.0.tgz#3f4a08d6303a09882cef3f0fb97439c5f5ce2d53"
|
||||||
dependencies:
|
dependencies:
|
||||||
ci-info "^1.0.0"
|
ci-info "^1.3.0"
|
||||||
|
|
||||||
is-color-stop@^1.0.0:
|
is-color-stop@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
|
@ -4019,7 +3962,7 @@ is-resolvable@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
|
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
|
||||||
|
|
||||||
is-stream@^1.0.1, is-stream@^1.1.0:
|
is-stream@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||||
|
|
||||||
|
@ -4323,10 +4266,6 @@ lodash.defaultsdeep@^4.6.0:
|
||||||
version "4.6.0"
|
version "4.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz#bec1024f85b1bd96cbea405b23c14ad6443a6f81"
|
resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz#bec1024f85b1bd96cbea405b23c14ad6443a6f81"
|
||||||
|
|
||||||
lodash.get@^4.4.2:
|
|
||||||
version "4.4.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
|
||||||
|
|
||||||
lodash.mapvalues@^4.6.0:
|
lodash.mapvalues@^4.6.0:
|
||||||
version "4.6.0"
|
version "4.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"
|
resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"
|
||||||
|
@ -4335,10 +4274,6 @@ lodash.memoize@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
|
|
||||||
lodash.startcase@^4.4.0:
|
|
||||||
version "4.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8"
|
|
||||||
|
|
||||||
lodash.transform@^4.6.0:
|
lodash.transform@^4.6.0:
|
||||||
version "4.6.0"
|
version "4.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0"
|
resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0"
|
||||||
|
@ -4588,7 +4523,7 @@ minimist@0.0.8:
|
||||||
version "0.0.8"
|
version "0.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||||
|
|
||||||
minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0:
|
minimist@^1.1.3, minimist@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||||
|
|
||||||
|
@ -4633,7 +4568,7 @@ mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@
|
||||||
dependencies:
|
dependencies:
|
||||||
minimist "0.0.8"
|
minimist "0.0.8"
|
||||||
|
|
||||||
moment@^2.22.2:
|
moment@^2.18.1:
|
||||||
version "2.22.2"
|
version "2.22.2"
|
||||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
|
||||||
|
|
||||||
|
@ -4704,8 +4639,8 @@ negotiator@0.6.1:
|
||||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
|
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
|
||||||
|
|
||||||
neo-async@^2.5.0:
|
neo-async@^2.5.0:
|
||||||
version "2.5.1"
|
version "2.5.2"
|
||||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee"
|
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.2.tgz#489105ce7bc54e709d736b195f82135048c50fcc"
|
||||||
|
|
||||||
next-tick@1:
|
next-tick@1:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
|
@ -4721,13 +4656,6 @@ no-case@^2.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
lower-case "^1.1.1"
|
lower-case "^1.1.1"
|
||||||
|
|
||||||
node-fetch@1.6.3:
|
|
||||||
version "1.6.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04"
|
|
||||||
dependencies:
|
|
||||||
encoding "^0.1.11"
|
|
||||||
is-stream "^1.0.1"
|
|
||||||
|
|
||||||
node-forge@0.7.5:
|
node-forge@0.7.5:
|
||||||
version "0.7.5"
|
version "0.7.5"
|
||||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
|
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
|
||||||
|
@ -4883,7 +4811,7 @@ object-hash@^1.1.4:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2"
|
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2"
|
||||||
|
|
||||||
object-keys@^1.0.11, object-keys@^1.0.8:
|
object-keys@^1.0.11, object-keys@^1.0.12:
|
||||||
version "1.0.12"
|
version "1.0.12"
|
||||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
|
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
|
||||||
|
|
||||||
|
@ -4957,28 +4885,10 @@ onetime@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-fn "^1.0.0"
|
mimic-fn "^1.0.0"
|
||||||
|
|
||||||
opencollective@^1.0.3:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1"
|
|
||||||
dependencies:
|
|
||||||
babel-polyfill "6.23.0"
|
|
||||||
chalk "1.1.3"
|
|
||||||
inquirer "3.0.6"
|
|
||||||
minimist "1.2.0"
|
|
||||||
node-fetch "1.6.3"
|
|
||||||
opn "4.0.2"
|
|
||||||
|
|
||||||
opener@^1.4.3:
|
opener@^1.4.3:
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.0.tgz#24222fb4ad423ba21f5bf38855cebe44220f6531"
|
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.0.tgz#24222fb4ad423ba21f5bf38855cebe44220f6531"
|
||||||
|
|
||||||
opn@4.0.2:
|
|
||||||
version "4.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95"
|
|
||||||
dependencies:
|
|
||||||
object-assign "^4.0.1"
|
|
||||||
pinkie-promise "^2.0.0"
|
|
||||||
|
|
||||||
opn@^5.1.0, opn@^5.3.0:
|
opn@^5.1.0, opn@^5.3.0:
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c"
|
resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c"
|
||||||
|
@ -5228,10 +5138,6 @@ pluralize@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
||||||
|
|
||||||
popper.js@^1.12.9:
|
|
||||||
version "1.14.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.4.tgz#8eec1d8ff02a5a3a152dd43414a15c7b79fd69b6"
|
|
||||||
|
|
||||||
portfinder@^1.0.13, portfinder@^1.0.9:
|
portfinder@^1.0.13, portfinder@^1.0.9:
|
||||||
version "1.0.16"
|
version "1.0.16"
|
||||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.16.tgz#a6a68be9c352bc66c1a4c17a261f661f3facaf52"
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.16.tgz#a6a68be9c352bc66c1a4c17a261f661f3facaf52"
|
||||||
|
@ -5702,7 +5608,7 @@ pug-walk@^1.1.7:
|
||||||
version "1.1.7"
|
version "1.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.7.tgz#c00d5c5128bac5806bec15d2b7e7cdabe42531f3"
|
resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.7.tgz#c00d5c5128bac5806bec15d2b7e7cdabe42531f3"
|
||||||
|
|
||||||
pug@^2.0.3:
|
pug@^2.0.1:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.3.tgz#71cba82537c95a5eab7ed04696e4221f53aa878e"
|
resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.3.tgz#71cba82537c95a5eab7ed04696e4221f53aa878e"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -5901,10 +5807,6 @@ regenerate@^1.2.1, regenerate@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
||||||
|
|
||||||
regenerator-runtime@^0.10.0:
|
|
||||||
version "0.10.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
|
|
||||||
|
|
||||||
regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1:
|
regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1:
|
||||||
version "0.11.1"
|
version "0.11.1"
|
||||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
||||||
|
@ -6149,10 +6051,6 @@ rx-lite@*, rx-lite@^4.0.8:
|
||||||
version "4.0.8"
|
version "4.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
|
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
|
||||||
|
|
||||||
rx@^4.1.0:
|
|
||||||
version "4.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
|
|
||||||
|
|
||||||
safe-buffer@5.1.1:
|
safe-buffer@5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||||
|
@ -6175,13 +6073,21 @@ sax@^1.2.4, sax@~1.2.4:
|
||||||
version "1.2.4"
|
version "1.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||||
|
|
||||||
schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.3, schema-utils@^0.4.4, schema-utils@^0.4.5:
|
schema-utils@^0.4.0, schema-utils@^0.4.2, schema-utils@^0.4.4, schema-utils@^0.4.5:
|
||||||
version "0.4.7"
|
version "0.4.7"
|
||||||
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"
|
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv "^6.1.0"
|
ajv "^6.1.0"
|
||||||
ajv-keywords "^3.1.0"
|
ajv-keywords "^3.1.0"
|
||||||
|
|
||||||
|
schema-utils@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
|
||||||
|
dependencies:
|
||||||
|
ajv "^6.1.0"
|
||||||
|
ajv-errors "^1.0.0"
|
||||||
|
ajv-keywords "^3.1.0"
|
||||||
|
|
||||||
select-hose@^2.0.0:
|
select-hose@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||||
|
@ -6193,8 +6099,8 @@ selfsigned@^1.9.1:
|
||||||
node-forge "0.7.5"
|
node-forge "0.7.5"
|
||||||
|
|
||||||
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0:
|
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0:
|
||||||
version "5.5.0"
|
version "5.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
|
||||||
|
|
||||||
send@0.16.2:
|
send@0.16.2:
|
||||||
version "0.16.2"
|
version "0.16.2"
|
||||||
|
@ -6866,8 +6772,8 @@ uglify-to-browserify@~1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
|
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
|
||||||
|
|
||||||
uglifyjs-webpack-plugin@^1.2.4, uglifyjs-webpack-plugin@^1.2.7:
|
uglifyjs-webpack-plugin@^1.2.4, uglifyjs-webpack-plugin@^1.2.7:
|
||||||
version "1.2.7"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz#57638dd99c853a1ebfe9d97b42160a8a507f9d00"
|
resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de"
|
||||||
dependencies:
|
dependencies:
|
||||||
cacache "^10.0.4"
|
cacache "^10.0.4"
|
||||||
find-cache-dir "^1.0.0"
|
find-cache-dir "^1.0.0"
|
||||||
|
@ -6953,7 +6859,7 @@ upper-case@^1.1.1:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
|
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
|
||||||
|
|
||||||
uri-js@^4.2.1:
|
uri-js@^4.2.2:
|
||||||
version "4.2.2"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6971,13 +6877,13 @@ url-join@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
|
resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
|
||||||
|
|
||||||
url-loader@^1.0.1:
|
url-loader@^1.1.0:
|
||||||
version "1.0.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.0.1.tgz#61bc53f1f184d7343da2728a1289ef8722ea45ee"
|
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.1.tgz#4d1f3b4f90dde89f02c008e662d604d7511167c1"
|
||||||
dependencies:
|
dependencies:
|
||||||
loader-utils "^1.1.0"
|
loader-utils "^1.1.0"
|
||||||
mime "^2.0.3"
|
mime "^2.0.3"
|
||||||
schema-utils "^0.4.3"
|
schema-utils "^1.0.0"
|
||||||
|
|
||||||
url-parse@^1.1.8, url-parse@^1.4.3:
|
url-parse@^1.1.8, url-parse@^1.4.3:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
|
@ -7069,10 +6975,6 @@ void-elements@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
||||||
|
|
||||||
vue-awesome@^2.3.3:
|
|
||||||
version "2.3.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/vue-awesome/-/vue-awesome-2.3.8.tgz#95ed4fb7f84453603f0931f865238576e55582a4"
|
|
||||||
|
|
||||||
vue-eslint-parser@^2.0.3:
|
vue-eslint-parser@^2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1"
|
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1"
|
||||||
|
@ -7084,10 +6986,6 @@ vue-eslint-parser@^2.0.3:
|
||||||
esquery "^1.0.0"
|
esquery "^1.0.0"
|
||||||
lodash "^4.17.4"
|
lodash "^4.17.4"
|
||||||
|
|
||||||
vue-functional-data-merge@^2.0.5:
|
|
||||||
version "2.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/vue-functional-data-merge/-/vue-functional-data-merge-2.0.6.tgz#f08055adfb92458debcf2ad10c3aa712277f7fc2"
|
|
||||||
|
|
||||||
vue-hot-reload-api@^2.3.0:
|
vue-hot-reload-api@^2.3.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz#97976142405d13d8efae154749e88c4e358cf926"
|
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz#97976142405d13d8efae154749e88c4e358cf926"
|
||||||
|
@ -7102,17 +7000,17 @@ vue-loader@^15.3.0:
|
||||||
vue-hot-reload-api "^2.3.0"
|
vue-hot-reload-api "^2.3.0"
|
||||||
vue-style-loader "^4.1.0"
|
vue-style-loader "^4.1.0"
|
||||||
|
|
||||||
vue-progressbar@^0.7.5:
|
vue-progressbar@^0.7.3:
|
||||||
version "0.7.5"
|
version "0.7.5"
|
||||||
resolved "https://registry.yarnpkg.com/vue-progressbar/-/vue-progressbar-0.7.5.tgz#414730892252b1e45582d4979dec93038e007f79"
|
resolved "https://registry.yarnpkg.com/vue-progressbar/-/vue-progressbar-0.7.5.tgz#414730892252b1e45582d4979dec93038e007f79"
|
||||||
|
|
||||||
vue-router@^3.0.1:
|
vue-router@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.1.tgz#d9b05ad9c7420ba0f626d6500d693e60092cc1e9"
|
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.1.tgz#d9b05ad9c7420ba0f626d6500d693e60092cc1e9"
|
||||||
|
|
||||||
vue-style-loader@^4.1.0:
|
vue-style-loader@^4.1.0:
|
||||||
version "4.1.1"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.1.tgz#7c1d051b24f60b1707602b549ed50b4c8111d316"
|
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8"
|
||||||
dependencies:
|
dependencies:
|
||||||
hash-sum "^1.0.2"
|
hash-sum "^1.0.2"
|
||||||
loader-utils "^1.0.2"
|
loader-utils "^1.0.2"
|
||||||
|
@ -7132,7 +7030,7 @@ vue-toast@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/vue-toast/-/vue-toast-3.1.0.tgz#19eb4c8150faf5c31c12f8b897a955d1ac0b5e9e"
|
resolved "https://registry.yarnpkg.com/vue-toast/-/vue-toast-3.1.0.tgz#19eb4c8150faf5c31c12f8b897a955d1ac0b5e9e"
|
||||||
|
|
||||||
vue@^2.5.17:
|
vue@^2.5.15:
|
||||||
version "2.5.17"
|
version "2.5.17"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada"
|
||||||
|
|
||||||
|
@ -7178,8 +7076,8 @@ webpack-bundle-analyzer@^2.13.1:
|
||||||
ws "^4.0.0"
|
ws "^4.0.0"
|
||||||
|
|
||||||
webpack-chain@^4.8.0:
|
webpack-chain@^4.8.0:
|
||||||
version "4.8.0"
|
version "4.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.8.0.tgz#06fc3dbb9f2707d4c9e899fc6250fbcf2afe6fd1"
|
resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.9.0.tgz#2f0794d34d79a7cc5db1416f497b76ad33df30ee"
|
||||||
dependencies:
|
dependencies:
|
||||||
deepmerge "^1.5.2"
|
deepmerge "^1.5.2"
|
||||||
javascript-stringify "^1.6.0"
|
javascript-stringify "^1.6.0"
|
||||||
|
|
31
src/sql/16-recurrence.sql
Normal file
31
src/sql/16-recurrence.sql
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
ALTER TABLE mpj.request
|
||||||
|
ADD COLUMN "showAfter" BIGINT NOT NULL DEFAULT 0;
|
||||||
|
ALTER TABLE mpj.request
|
||||||
|
ADD COLUMN "recurType" VARCHAR(10) NOT NULL DEFAULT 'immediate';
|
||||||
|
ALTER TABLE mpj.request
|
||||||
|
ADD COLUMN "recurCount" SMALLINT NOT NULL DEFAULT 0;
|
||||||
|
CREATE OR REPLACE VIEW mpj.journal AS
|
||||||
|
SELECT
|
||||||
|
request."requestId",
|
||||||
|
request."userId",
|
||||||
|
(SELECT "text"
|
||||||
|
FROM mpj.history
|
||||||
|
WHERE history."requestId" = request."requestId"
|
||||||
|
AND "text" IS NOT NULL
|
||||||
|
ORDER BY "asOf" DESC
|
||||||
|
LIMIT 1) AS "text",
|
||||||
|
(SELECT "asOf"
|
||||||
|
FROM mpj.history
|
||||||
|
WHERE history."requestId" = request."requestId"
|
||||||
|
ORDER BY "asOf" DESC
|
||||||
|
LIMIT 1) AS "asOf",
|
||||||
|
(SELECT "status"
|
||||||
|
FROM mpj.history
|
||||||
|
WHERE history."requestId" = request."requestId"
|
||||||
|
ORDER BY "asOf" DESC
|
||||||
|
LIMIT 1) AS "lastStatus",
|
||||||
|
request."snoozedUntil",
|
||||||
|
request."showAfter",
|
||||||
|
request."recurType",
|
||||||
|
request."recurCount"
|
||||||
|
FROM mpj.request;
|
Loading…
Reference in New Issue
Block a user