Completed recurrence work (#16)
Requests can now: - be entered with recurrence - be updated with recurrence - manually skip recurrence period Also did an app-wide clean-up to ensure that everything is done the same way in all places
This commit is contained in:
parent
9f1e258180
commit
2c34650ceb
@ -245,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
|
||||||
|
@ -95,6 +95,15 @@ 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 =
|
||||||
@ -103,9 +112,16 @@ module Models =
|
|||||||
/// The recurrence type
|
/// The recurrence type
|
||||||
recurType : string
|
recurType : string
|
||||||
/// The recurrence count
|
/// The recurrence count
|
||||||
recurCount : int16 option
|
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 =
|
||||||
@ -156,7 +172,7 @@ module Request =
|
|||||||
enteredOn = now
|
enteredOn = now
|
||||||
showAfter = now
|
showAfter = now
|
||||||
recurType = r.recurType
|
recurType = r.recurType
|
||||||
recurCount = defaultArg r.recurCount 0s
|
recurCount = r.recurCount
|
||||||
}
|
}
|
||||||
|> db.AddEntry
|
|> db.AddEntry
|
||||||
{ History.empty with
|
{ History.empty with
|
||||||
@ -255,7 +271,23 @@ 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 show reqId : HttpHandler =
|
||||||
|
authorize
|
||||||
|
>=> fun next ctx ->
|
||||||
|
task {
|
||||||
|
let db = db ctx
|
||||||
|
match! db.TryRequestById reqId (userId ctx) with
|
||||||
|
| Some req ->
|
||||||
|
let! show = ctx.BindJsonAsync<Models.Show> ()
|
||||||
|
{ req with showAfter = show.showAfter }
|
||||||
|
|> 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 =
|
let snooze reqId : HttpHandler =
|
||||||
authorize
|
authorize
|
||||||
>=> fun next ctx ->
|
>=> fun next ctx ->
|
||||||
@ -270,3 +302,19 @@ module Request =
|
|||||||
return! setStatusCode 204 next ctx
|
return! setStatusCode 204 next ctx
|
||||||
| None -> return! Error.notFound 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
|
||||||
|
let! _ = db.SaveChangesAsync ()
|
||||||
|
return! setStatusCode 204 next ctx
|
||||||
|
| None -> return! Error.notFound next ctx
|
||||||
|
}
|
||||||
|
@ -58,10 +58,17 @@ module Configure =
|
|||||||
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/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 [
|
||||||
@ -69,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
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<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'
|
||||||
|
|
||||||
@ -74,8 +74,15 @@ h5 {
|
|||||||
p {
|
p {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
input, textarea {
|
input, textarea, select {
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;
|
||||||
|
}
|
||||||
|
input, select {
|
||||||
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
button,
|
button,
|
||||||
a[role="button"] {
|
a[role="button"] {
|
||||||
@ -183,6 +190,9 @@ a:hover {
|
|||||||
max-width: 20rem;
|
max-width: 20rem;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
.mpj-full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.mpj-modal {
|
.mpj-modal {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 8;
|
z-index: 8;
|
||||||
|
@ -32,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, recurType: 'immediate' }),
|
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
|
||||||
@ -64,19 +66,33 @@ export default {
|
|||||||
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
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,8 @@ export default {
|
|||||||
...mapState(['journal', 'isLoadingJournal'])
|
...mapState(['journal', 'isLoadingJournal'])
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.$on('requestSnoozed', this.ensureJournal)
|
this.$on('requestUnsnoozed', this.ensureJournal)
|
||||||
|
this.$on('requestNowShown', this.ensureJournal)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async ensureJournal () {
|
async ensureJournal () {
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
article.mpj-main-content(role='main')
|
article.mpj-main-content(role='main')
|
||||||
page-title(:title='title')
|
page-title(:title='title')
|
||||||
.mpj-narrow
|
.mpj-narrow
|
||||||
label(for='request_text') Prayer Request
|
label(for='request_text')
|
||||||
br
|
| Prayer Request
|
||||||
textarea#request_text(v-model='form.requestText'
|
br
|
||||||
:rows='10'
|
textarea(v-model='form.requestText'
|
||||||
@blur='trimText()'
|
:rows='10'
|
||||||
autofocus)
|
@blur='trimText()'
|
||||||
|
autofocus).mpj-full-width
|
||||||
br
|
br
|
||||||
template(v-if='!isNew')
|
template(v-if='!isNew')
|
||||||
label Also Mark As
|
label Also Mark As
|
||||||
@ -50,22 +51,21 @@ article.mpj-main-content(role='main')
|
|||||||
name='recur'
|
name='recur'
|
||||||
value='other')
|
value='other')
|
||||||
| Every...
|
| Every...
|
||||||
input#recur_count(v-model='form.recur.count'
|
input(v-model='form.recur.count'
|
||||||
type='number'
|
type='number'
|
||||||
:disabled='!showRecurrence')
|
:disabled='!showRecurrence').mpj-recur-count
|
||||||
select(v-model='form.recur.other'
|
select(v-model='form.recur.other'
|
||||||
:disabled='!showRecurrence')
|
:disabled='!showRecurrence').mpj-recur-type
|
||||||
option(value='hours') hours
|
option(value='hours') hours
|
||||||
option(value='days') days
|
option(value='days') days
|
||||||
option(value='weeks') weeks
|
option(value='weeks') weeks
|
||||||
.mpj-text-right
|
.mpj-text-right
|
||||||
button(@click.stop='saveRequest()').primary
|
button(:disabled='!isValidRecurrence'
|
||||||
md-icon(icon='save')
|
@click.stop='saveRequest()').primary.
|
||||||
= ' Save'
|
#[md-icon(icon='save')] Save
|
||||||
|
|
|
|
||||||
button(@click.stop='goBack()')
|
button(@click.stop='goBack()').
|
||||||
md-icon(icon='arrow_back')
|
#[md-icon(icon='arrow_back')] Cancel
|
||||||
= ' Cancel'
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -100,15 +100,25 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
toast () {
|
isValidRecurrence () {
|
||||||
return this.$parent.$refs.toast
|
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 () {
|
showRecurrence () {
|
||||||
this.form.recur.typ !== 'immediate'
|
return this.form.recur.typ !== 'immediate'
|
||||||
|
},
|
||||||
|
toast () {
|
||||||
|
return this.$parent.$refs.toast
|
||||||
},
|
},
|
||||||
...mapState(['journal'])
|
...mapState(['journal'])
|
||||||
},
|
},
|
||||||
async mounted () {
|
async mounted () {
|
||||||
|
await this.ensureJournal()
|
||||||
if (this.id === 'new') {
|
if (this.id === 'new') {
|
||||||
this.title = 'Add Prayer Request'
|
this.title = 'Add Prayer Request'
|
||||||
this.isNew = true
|
this.isNew = true
|
||||||
@ -146,11 +156,18 @@ export default {
|
|||||||
trimText () {
|
trimText () {
|
||||||
this.form.requestText = this.form.requestText.trim()
|
this.form.requestText = this.form.requestText.trim()
|
||||||
},
|
},
|
||||||
|
async ensureJournal () {
|
||||||
|
if (!Array.isArray(this.journal)) {
|
||||||
|
await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress)
|
||||||
|
}
|
||||||
|
},
|
||||||
async saveRequest () {
|
async saveRequest () {
|
||||||
if (this.isNew) {
|
if (this.isNew) {
|
||||||
await this.$store.dispatch(actions.ADD_REQUEST, {
|
await this.$store.dispatch(actions.ADD_REQUEST, {
|
||||||
progress: this.$Progress,
|
progress: this.$Progress,
|
||||||
requestText: this.form.requestText
|
requestText: this.form.requestText,
|
||||||
|
recurType: this.form.recur.typ === 'immediate' ? 'immediate' : this.form.recur.other,
|
||||||
|
recurCount: this.form.recur.typ === 'immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
||||||
})
|
})
|
||||||
this.toast.showToast('New prayer request added', { theme: 'success' })
|
this.toast.showToast('New prayer request added', { theme: 'success' })
|
||||||
} else {
|
} else {
|
||||||
@ -158,7 +175,9 @@ export default {
|
|||||||
progress: this.$Progress,
|
progress: this.$Progress,
|
||||||
requestId: this.form.requestId,
|
requestId: this.form.requestId,
|
||||||
updateText: this.form.requestText,
|
updateText: this.form.requestText,
|
||||||
status: this.form.status
|
status: this.form.status,
|
||||||
|
recurType: this.form.recur.typ === 'immediate' ? 'immediate' : this.form.recur.other,
|
||||||
|
recurCount: this.form.recur.typ === 'immediate' ? 0 : Number.parseInt(this.form.recur.count)
|
||||||
})
|
})
|
||||||
if (this.form.status === 'Answered') {
|
if (this.form.status === 'Answered') {
|
||||||
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
|
this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
|
||||||
@ -172,11 +191,14 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
#request_text {
|
.mpj-recur-count {
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
#recur_count {
|
|
||||||
width: 3rem;
|
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>
|
</style>
|
||||||
|
@ -55,11 +55,12 @@ export default {
|
|||||||
.sort(asOfDesc)[0].text.fields[0]
|
.sort(asOfDesc)[0].text.fields[0]
|
||||||
},
|
},
|
||||||
log () {
|
log () {
|
||||||
return (this.request.notes || [])
|
const allHistory = (this.request.notes || [])
|
||||||
.map(note => ({ asOf: note.asOf, text: { case: 'Some', fields: [ note.notes ] }, status: 'Notes' }))
|
.map(note => ({ asOf: note.asOf, text: { case: 'Some', fields: [ note.notes ] }, status: 'Notes' }))
|
||||||
.concat(this.request.history)
|
.concat(this.request.history)
|
||||||
.sort(asOfDesc)
|
.sort(asOfDesc)
|
||||||
.slice(1)
|
// Skip the first entry for answered requests; that info is already displayed
|
||||||
|
return this.isAnswered ? allHistory.slice(1) : allHistory
|
||||||
},
|
},
|
||||||
openDays () {
|
openDays () {
|
||||||
const asOf = this.isAnswered ? this.answered : Date.now()
|
const asOf = this.isAnswered ? this.answered : Date.now()
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
<template lang="pug">
|
|
||||||
div
|
|
||||||
button(@click='openDialog()')
|
|
||||||
md-icon(icon='add_box')
|
|
||||||
| 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()')
|
|
||||||
b-form-group(label='Recurrence')
|
|
||||||
| After prayer, request reappears
|
|
||||||
b-radio(v-model='form.recur.typ'
|
|
||||||
label='Immediately'
|
|
||||||
value='immediately'
|
|
||||||
checked='checked'
|
|
||||||
@click='checkRadios')
|
|
||||||
b-radio(v-model='form.recur.typ'
|
|
||||||
label='Every...'
|
|
||||||
value='other'
|
|
||||||
@click='checkRadios')
|
|
||||||
b-input(v-model='form.recur.count'
|
|
||||||
placeholder='##')
|
|
||||||
b-select(v-model='form.recur.other')
|
|
||||||
b-option(value='hours') hours
|
|
||||||
b-option(value='days') days
|
|
||||||
b-option(value='weeks') weeks
|
|
||||||
div.w-100.text-right(slot='modal-footer')
|
|
||||||
b-btn(variant='primary'
|
|
||||||
:disabled='!isValid'
|
|
||||||
@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: '',
|
|
||||||
recur: {
|
|
||||||
typ: 'immediate',
|
|
||||||
other: '',
|
|
||||||
count: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
formLabelWidth: '120px'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
this.$refs.toast.setOptions({ position: 'bottom right' })
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isValid () {
|
|
||||||
// TODO disallow submission if recurrence is too long
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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>
|
|
@ -3,11 +3,12 @@
|
|||||||
.mpj-modal-content.mpj-narrow
|
.mpj-modal-content.mpj-narrow
|
||||||
header.mpj-bg
|
header.mpj-bg
|
||||||
h5 Add Notes to Prayer Request
|
h5 Add Notes to Prayer Request
|
||||||
label(for='notes') Notes
|
label
|
||||||
br
|
| Notes
|
||||||
textarea#notes(v-model='form.notes'
|
br
|
||||||
:rows='10'
|
textarea(v-model='form.notes'
|
||||||
@blur='trimText()')
|
:rows='10'
|
||||||
|
@blur='trimText()').mpj-full-width
|
||||||
.mpj-text-right
|
.mpj-text-right
|
||||||
button(@click='saveNotes()').primary.
|
button(@click='saveNotes()').primary.
|
||||||
#[md-icon(icon='save')] Save
|
#[md-icon(icon='save')] Save
|
||||||
@ -75,7 +76,6 @@ export default {
|
|||||||
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)
|
||||||
@ -85,7 +85,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
openDialog (request) {
|
openDialog (request) {
|
||||||
console.log('Received openDialog event')
|
|
||||||
this.form.requestId = request.requestId
|
this.form.requestId = request.requestId
|
||||||
this.notesVisible = true
|
this.notesVisible = true
|
||||||
},
|
},
|
||||||
@ -108,10 +107,7 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
#notes {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.mpj-note-list p {
|
.mpj-note-list p {
|
||||||
border-top: dotted 1px lightgray;
|
border-top: dotted 1px lightgray;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
.mpj-request-card
|
.mpj-request-card(v-if='shouldDisplay')
|
||||||
header.mpj-card-header(role='toolbar').
|
header.mpj-card-header(role='toolbar').
|
||||||
#[button.primary(@click='markPrayed()' title='Pray'): md-icon(icon='done')]
|
#[button(@click='markPrayed()' title='Pray').primary: md-icon(icon='done')]
|
||||||
#[button(@click.stop='showEdit()' title='Edit'): md-icon(icon='edit')]
|
#[button(@click.stop='showEdit()' title='Edit'): md-icon(icon='edit')]
|
||||||
#[button(@click.stop='showNotes()' title='Add Notes'): md-icon(icon='comment')]
|
#[button(@click.stop='showNotes()' title='Add Notes'): md-icon(icon='comment')]
|
||||||
#[button(@click.stop='snooze()' title='Snooze Request'): md-icon(icon='schedule')]
|
#[button(@click.stop='snooze()' title='Snooze Request'): md-icon(icon='schedule')]
|
||||||
|
@ -7,17 +7,23 @@ p.mpj-request-text
|
|||||||
title='View Full Request').
|
title='View Full Request').
|
||||||
#[md-icon(icon='description')] View Full Request
|
#[md-icon(icon='description')] View Full Request
|
||||||
|
|
|
|
||||||
button(v-if='!isAnswered'
|
template(v-if='!isAnswered')
|
||||||
@click='editRequest'
|
button(@click='editRequest'
|
||||||
title='Edit Request').
|
title='Edit Request').
|
||||||
#[md-icon(icon='edit')] Edit Request
|
#[md-icon(icon='edit')] Edit Request
|
||||||
|
|
|
|
||||||
button(v-if='isSnoozed'
|
template(v-if='isSnoozed')
|
||||||
@click='cancelSnooze()').
|
button(@click='cancelSnooze()').
|
||||||
#[md-icon(icon='restore')] Cancel Snooze
|
#[md-icon(icon='restore')] Cancel Snooze
|
||||||
br(v-if='isSnoozed || isAnswered')
|
|
|
||||||
|
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.
|
small(v-if='isSnoozed').mpj-muted-text: em.
|
||||||
Snooze expires #[date-from-now(:value='request.snoozedUntil')]
|
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.
|
small(v-if='isAnswered').mpj-muted-text: em.
|
||||||
Answered #[date-from-now(:value='request.asOf')]
|
Answered #[date-from-now(:value='request.asOf')]
|
||||||
</template>
|
</template>
|
||||||
@ -43,6 +49,9 @@ export default {
|
|||||||
isAnswered () {
|
isAnswered () {
|
||||||
return this.request.lastStatus === 'Answered'
|
return this.request.lastStatus === 'Answered'
|
||||||
},
|
},
|
||||||
|
isPending () {
|
||||||
|
return !this.isSnoozed && this.request.showAfter > Date.now()
|
||||||
|
},
|
||||||
isSnoozed () {
|
isSnoozed () {
|
||||||
return this.request.snoozedUntil > Date.now()
|
return this.request.snoozedUntil > Date.now()
|
||||||
}
|
}
|
||||||
@ -60,6 +69,15 @@ export default {
|
|||||||
editRequest () {
|
editRequest () {
|
||||||
this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
|
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 () {
|
viewFull () {
|
||||||
this.$router.push({ name: 'FullRequest', params: { id: this.request.requestId } })
|
this.$router.push({ name: 'FullRequest', params: { id: this.request.requestId } })
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
header.mpj-bg
|
header.mpj-bg
|
||||||
h5 Snooze Prayer Request
|
h5 Snooze Prayer Request
|
||||||
p.mpj-text-center
|
p.mpj-text-center
|
||||||
label(for='until') Until
|
label
|
||||||
= ' '
|
= 'Until '
|
||||||
input#until(type='date'
|
input(v-model='form.snoozedUntil'
|
||||||
v-model='form.snoozedUntil'
|
type='date'
|
||||||
autofocus)
|
autofocus)
|
||||||
br
|
br
|
||||||
.mpj-text-right
|
.mpj-text-right
|
||||||
button.primary(:disabled='!isValid'
|
button.primary(:disabled='!isValid'
|
||||||
|
@ -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>
|
||||||
|
@ -18,6 +18,13 @@ Vue.use(Router)
|
|||||||
|
|
||||||
export default new Router({
|
export default new Router({
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
|
scrollBehavior (to, from, savedPosition) {
|
||||||
|
if (savedPosition) {
|
||||||
|
return savedPosition
|
||||||
|
} else {
|
||||||
|
return { x: 0, y: 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
|
@ -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'
|
||||||
}
|
}
|
||||||
|
@ -73,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) {
|
||||||
@ -100,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()
|
||||||
|
Loading…
Reference in New Issue
Block a user