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:
Daniel J. Summers 2018-08-18 19:32:48 -05:00
parent 9f1e258180
commit 2c34650ceb
18 changed files with 228 additions and 183 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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
] ]
] ]
] ]

View File

@ -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;

View File

@ -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
})
} }

View File

@ -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 () {

View File

@ -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
| &nbsp; &nbsp; | &nbsp; &nbsp;
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>

View File

@ -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()

View File

@ -1,100 +0,0 @@
<template lang="pug">
div
button(@click='openDialog()')
md-icon(icon='add_box')
| &nbsp; 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
| &nbsp; &nbsp;
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>

View File

@ -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;
} }

View File

@ -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')]

View File

@ -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
| &nbsp; &nbsp; | &nbsp; &nbsp;
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
| &nbsp; &nbsp; | &nbsp; &nbsp;
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') | &nbsp; &nbsp;
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.
&nbsp; Snooze expires #[date-from-now(:value='request.snoozedUntil')] &nbsp; Snooze expires #[date-from-now(:value='request.snoozedUntil')]
small(v-if='isPending').mpj-muted-text: em.
&nbsp; 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.
&nbsp; Answered #[date-from-now(:value='request.asOf')] &nbsp; 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 } })
} }

View File

@ -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'

View File

@ -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>

View File

@ -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: '/',

View File

@ -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'
} }

View File

@ -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()