Version 3 #67
@ -35,7 +35,7 @@ import Vue from 'vue'
|
|||||||
|
|
||||||
import Navigation from '@/components/common/Navigation'
|
import Navigation from '@/components/common/Navigation'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
import { version } from '../package.json'
|
import { version } from '../package.json'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -63,7 +63,7 @@ export default {
|
|||||||
this.progress.events.$on('done', this.hideProgress)
|
this.progress.events.$on('done', this.hideProgress)
|
||||||
this.snackbar.events.$on('info', this.showInfo)
|
this.snackbar.events.$on('info', this.showInfo)
|
||||||
this.snackbar.events.$on('error', this.showError)
|
this.snackbar.events.$on('error', this.showError)
|
||||||
await this.$store.dispatch(actions.CHECK_AUTHENTICATION)
|
await this.$store.dispatch(Actions.CheckAuthentication)
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
version () {
|
version () {
|
||||||
|
@ -13,9 +13,9 @@ export default {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the bearer token for all future requests
|
* Set the bearer token for all future requests
|
||||||
* @param {string} token The token to use to identify the user to the server
|
* @param token The token to use to identify the user to the server
|
||||||
*/
|
*/
|
||||||
setBearer: token => { http.defaults.headers.common.Authorization = `Bearer ${token}` },
|
setBearer: (token: string) => { http.defaults.headers.common.Authorization = `Bearer ${token}` },
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the bearer token
|
* Remove the bearer token
|
||||||
@ -24,18 +24,19 @@ export default {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a note for a prayer request
|
* Add a note for a prayer request
|
||||||
* @param {string} requestId The Id of the request to which the note applies
|
* @param requestId The Id of the request to which the note applies
|
||||||
* @param {string} notes The notes to be added
|
* @param notes The notes to be added
|
||||||
*/
|
*/
|
||||||
addNote: (requestId, notes) => http.post(`request/${requestId}/note`, { notes }),
|
addNote: (requestId: string, notes: string) => http.post(`request/${requestId}/note`, { notes }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new prayer request
|
* Add a new prayer request
|
||||||
* @param {string} requestText The text of the request to be added
|
* @param requestText The text of the request to be added
|
||||||
* @param {string} recurType The type of recurrence for this request
|
* @param recurType The type of recurrence for this request
|
||||||
* @param {number} recurCount The number of intervals of recurrence
|
* @param recurCount The number of intervals of recurrence
|
||||||
*/
|
*/
|
||||||
addRequest: (requestText, recurType, recurCount) => http.post('request', { requestText, recurType, recurCount }),
|
addRequest: (requestText: string, recurType: string, recurCount: number) =>
|
||||||
|
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
|
||||||
@ -44,21 +45,21 @@ export default {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a prayer request (full; includes all history and notes)
|
* Get a prayer request (full; includes all history and notes)
|
||||||
* @param {string} requestId The Id of the request to retrieve
|
* @param requestId The Id of the request to retrieve
|
||||||
*/
|
*/
|
||||||
getFullRequest: requestId => http.get(`request/${requestId}/full`),
|
getFullRequest: (requestId: string) => http.get(`request/${requestId}/full`),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get past notes for a prayer request
|
* Get past notes for a prayer request
|
||||||
* @param {string} requestId The Id of the request for which notes should be retrieved
|
* @param requestId The Id of the request for which notes should be retrieved
|
||||||
*/
|
*/
|
||||||
getNotes: requestId => http.get(`request/${requestId}/notes`),
|
getNotes: (requestId: string) => http.get(`request/${requestId}/notes`),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a prayer request (journal-style; only latest update)
|
* Get a prayer request (journal-style; only latest update)
|
||||||
* @param {string} requestId The Id of the request to retrieve
|
* @param requestId The Id of the request to retrieve
|
||||||
*/
|
*/
|
||||||
getRequest: requestId => http.get(`request/${requestId}`),
|
getRequest: (requestId: string) => http.get(`request/${requestId}`),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all prayer requests and their most recent updates
|
* Get all prayer requests and their most recent updates
|
||||||
@ -67,32 +68,33 @@ export default {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a request after the given date (used for "show now")
|
* Show a request after the given date (used for "show now")
|
||||||
* @param {string} requestId The ID of the request which should be shown
|
* @param requestId The ID of the request which should be shown
|
||||||
* @param {number} showAfter The ticks after which the request should be shown
|
* @param showAfter The ticks after which the request should be shown
|
||||||
*/
|
*/
|
||||||
showRequest: (requestId, showAfter) => http.patch(`request/${requestId}/show`, { showAfter }),
|
showRequest: (requestId: string, showAfter: number) => http.patch(`request/${requestId}/show`, { showAfter }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Snooze a request until the given time
|
* Snooze a request until the given time
|
||||||
* @param {string} requestId The ID of the prayer request to be snoozed
|
* @param requestId The ID of the prayer request to be snoozed
|
||||||
* @param {number} until The ticks until which the request should be snoozed
|
* @param until The ticks until which the request should be snoozed
|
||||||
*/
|
*/
|
||||||
snoozeRequest: (requestId, until) => http.patch(`request/${requestId}/snooze`, { until }),
|
snoozeRequest: (requestId: string, until: number) => http.patch(`request/${requestId}/snooze`, { until }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update recurrence for a prayer request
|
* Update recurrence for a prayer request
|
||||||
* @param {string} requestId The ID of the prayer request for which recurrence is being updated
|
* @param requestId The ID of the prayer request for which recurrence is being updated
|
||||||
* @param {string} recurType The type of recurrence to set
|
* @param recurType The type of recurrence to set
|
||||||
* @param {number} recurCount The number of recurrence intervals to set
|
* @param recurCount The number of recurrence intervals to set
|
||||||
*/
|
*/
|
||||||
updateRecurrence: (requestId, recurType, recurCount) =>
|
updateRecurrence: (requestId: string, recurType: string, recurCount: number) =>
|
||||||
http.patch(`request/${requestId}/recurrence`, { recurType, recurCount }),
|
http.patch(`request/${requestId}/recurrence`, { recurType, recurCount }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a prayer request
|
* Update a prayer request
|
||||||
* @param {string} requestId The ID of the request to be updated
|
* @param requestId The ID of the request to be updated
|
||||||
* @param {string} status The status of the update
|
* @param status The status of the update
|
||||||
* @param {string} updateText The text of the update (optional)
|
* @param updateText The text of the update (optional)
|
||||||
*/
|
*/
|
||||||
updateRequest: (requestId, status, updateText) => http.post(`request/${requestId}/history`, { status, updateText })
|
updateRequest: (requestId: string, status: string, updateText: string) =>
|
||||||
|
http.post(`request/${requestId}/history`, { status, updateText })
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
'use strict'
|
import { Store } from 'vuex'
|
||||||
/* eslint-disable */
|
import auth0, { Auth0DecodedHash } from 'auth0-js'
|
||||||
import auth0 from 'auth0-js'
|
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
|
|
||||||
import AUTH_CONFIG from './auth0-variables'
|
import { Mutations, AppState } from '@/store/types'
|
||||||
import mutations from '@/store/mutation-types'
|
|
||||||
/* es-lint-enable*/
|
import Auth0Config from './auth0-variables'
|
||||||
|
import { Session } from './types'
|
||||||
|
|
||||||
// Auth0 web authentication instance to use for our calls
|
// Auth0 web authentication instance to use for our calls
|
||||||
const webAuth = new auth0.WebAuth({
|
const webAuth = new auth0.WebAuth({
|
||||||
domain: AUTH_CONFIG.domain,
|
domain: Auth0Config.domain,
|
||||||
clientID: AUTH_CONFIG.clientId,
|
clientID: Auth0Config.clientId,
|
||||||
redirectUri: AUTH_CONFIG.appDomain + AUTH_CONFIG.callbackUrl,
|
redirectUri: Auth0Config.appDomain + Auth0Config.callbackUrl,
|
||||||
audience: `https://${AUTH_CONFIG.domain}/userinfo`,
|
audience: `https://${Auth0Config.domain}/userinfo`,
|
||||||
responseType: 'token id_token',
|
responseType: 'token id_token',
|
||||||
scope: 'openid profile email'
|
scope: 'openid profile email'
|
||||||
})
|
})
|
||||||
@ -21,14 +21,13 @@ const webAuth = new auth0.WebAuth({
|
|||||||
* A class to handle all authentication calls and determinations
|
* A class to handle all authentication calls and determinations
|
||||||
*/
|
*/
|
||||||
class AuthService extends EventEmitter {
|
class AuthService extends EventEmitter {
|
||||||
|
|
||||||
// Local storage key for our session data
|
// Local storage key for our session data
|
||||||
AUTH_SESSION = 'auth-session'
|
AUTH_SESSION = 'auth-session'
|
||||||
|
|
||||||
// Received and calculated values for our ssesion (initially loaded from local storage if present)
|
// Received and calculated values for our ssesion (initially loaded from local storage if present)
|
||||||
session: any = {}
|
session = new Session()
|
||||||
|
|
||||||
constructor() {
|
constructor () {
|
||||||
super()
|
super()
|
||||||
this.refreshSession()
|
this.refreshSession()
|
||||||
}
|
}
|
||||||
@ -36,7 +35,7 @@ class AuthService extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Starts the user log in flow
|
* Starts the user log in flow
|
||||||
*/
|
*/
|
||||||
login (customState) {
|
login (customState: any) {
|
||||||
webAuth.authorize({
|
webAuth.authorize({
|
||||||
appState: customState
|
appState: customState
|
||||||
})
|
})
|
||||||
@ -45,10 +44,10 @@ class AuthService extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Promisified parseHash function
|
* Promisified parseHash function
|
||||||
*/
|
*/
|
||||||
parseHash () {
|
parseHash (): Promise<Auth0DecodedHash> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
webAuth.parseHash((err, authResult) => {
|
webAuth.parseHash((err, authResult) => {
|
||||||
if (err) {
|
if (err || authResult === null) {
|
||||||
reject(err)
|
reject(err)
|
||||||
} else {
|
} else {
|
||||||
resolve(authResult)
|
resolve(authResult)
|
||||||
@ -59,33 +58,31 @@ class AuthService extends EventEmitter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle authentication replies from Auth0
|
* Handle authentication replies from Auth0
|
||||||
*
|
|
||||||
* @param store The Vuex store
|
* @param store The Vuex store
|
||||||
*/
|
*/
|
||||||
async handleAuthentication (store) {
|
async handleAuthentication (store: Store<AppState>) {
|
||||||
try {
|
try {
|
||||||
const authResult: any = await this.parseHash()
|
const authResult = await this.parseHash()
|
||||||
if (authResult && authResult.accessToken && authResult.idToken) {
|
if (authResult && authResult.accessToken && authResult.idToken) {
|
||||||
this.setSession(authResult)
|
this.setSession(authResult)
|
||||||
store.commit(mutations.USER_LOGGED_ON, this.session.profile)
|
store.commit(Mutations.UserLoggedOn, this.session.profile)
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err) // eslint-disable-line no-console
|
||||||
alert(`Error: ${err.error}. Check the console for further details.`)
|
alert(`Error: ${err.error}. Check the console for further details.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the session and commit it to local storage
|
* Set up the session and commit it to local storage
|
||||||
*
|
|
||||||
* @param authResult The authorization result
|
* @param authResult The authorization result
|
||||||
*/
|
*/
|
||||||
setSession (authResult) {
|
setSession (authResult: Auth0DecodedHash) {
|
||||||
this.session.profile = authResult.idTokenPayload
|
this.session.profile = authResult.idTokenPayload
|
||||||
this.session.id.token = authResult.idToken
|
this.session.id.token = authResult.idToken!
|
||||||
this.session.id.expiry = this.session.profile.exp * 1000
|
this.session.id.expiry = this.session.profile.exp * 1000
|
||||||
this.session.access.token = authResult.accessToken
|
this.session.access.token = authResult.accessToken!
|
||||||
this.session.access.expiry = authResult.expiresIn * 1000 + Date.now()
|
this.session.access.expiry = authResult.expiresIn! * 1000 + Date.now()
|
||||||
|
|
||||||
localStorage.setItem(this.AUTH_SESSION, JSON.stringify(this.session))
|
localStorage.setItem(this.AUTH_SESSION, JSON.stringify(this.session))
|
||||||
|
|
||||||
@ -100,10 +97,8 @@ class AuthService extends EventEmitter {
|
|||||||
* Refresh this instance's session from the one in local storage
|
* Refresh this instance's session from the one in local storage
|
||||||
*/
|
*/
|
||||||
refreshSession () {
|
refreshSession () {
|
||||||
this.session =
|
const emptySession = {
|
||||||
localStorage.getItem(this.AUTH_SESSION)
|
profile: {},
|
||||||
? JSON.parse(localStorage.getItem(this.AUTH_SESSION) || '{}')
|
|
||||||
: { profile: {},
|
|
||||||
id: {
|
id: {
|
||||||
token: null,
|
token: null,
|
||||||
expiry: null
|
expiry: null
|
||||||
@ -113,12 +108,16 @@ class AuthService extends EventEmitter {
|
|||||||
expiry: null
|
expiry: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.session =
|
||||||
|
localStorage.getItem(this.AUTH_SESSION)
|
||||||
|
? JSON.parse(localStorage.getItem(this.AUTH_SESSION) || '{}')
|
||||||
|
: emptySession
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renew authorzation tokens with Auth0
|
* Renew authorzation tokens with Auth0
|
||||||
*/
|
*/
|
||||||
renewTokens () {
|
renewTokens (): Promise<Auth0DecodedHash> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.refreshSession()
|
this.refreshSession()
|
||||||
if (this.session.id.token !== null) {
|
if (this.session.id.token !== null) {
|
||||||
@ -126,67 +125,58 @@ class AuthService extends EventEmitter {
|
|||||||
if (err) {
|
if (err) {
|
||||||
reject(err)
|
reject(err)
|
||||||
} else {
|
} else {
|
||||||
this.setSession(authResult)
|
const result = authResult as Auth0DecodedHash
|
||||||
resolve(authResult)
|
this.setSession(result)
|
||||||
|
resolve(result)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
reject('Not logged in')
|
reject(new Error('Not logged in'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log out of myPrayerJournal
|
* Log out of myPrayerJournal
|
||||||
*
|
|
||||||
* @param store The Vuex store
|
* @param store The Vuex store
|
||||||
*/
|
*/
|
||||||
logout (store) {
|
logout (store: Store<AppState>) {
|
||||||
// Clear access token and ID token from local storage
|
// Clear access token and ID token from local storage
|
||||||
localStorage.removeItem(this.AUTH_SESSION)
|
localStorage.removeItem(this.AUTH_SESSION)
|
||||||
this.refreshSession()
|
this.refreshSession()
|
||||||
|
|
||||||
store.commit(mutations.USER_LOGGED_OFF)
|
store.commit(Mutations.UserLoggedOff)
|
||||||
|
|
||||||
webAuth.logout({
|
webAuth.logout({
|
||||||
returnTo: `${AUTH_CONFIG.appDomain}/`,
|
returnTo: `${Auth0Config.appDomain}/`,
|
||||||
clientID: AUTH_CONFIG.clientId
|
clientID: Auth0Config.clientId
|
||||||
})
|
})
|
||||||
this.emit('loginEvent', { loggedIn: false })
|
this.emit('loginEvent', { loggedIn: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check expiration for a token (the way it's stored in the session)
|
|
||||||
*/
|
|
||||||
checkExpiry = (it) => it.token && it.expiry && Date.now() < it.expiry
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is there a user authenticated?
|
* Is there a user authenticated?
|
||||||
*/
|
*/
|
||||||
isAuthenticated () {
|
isAuthenticated () {
|
||||||
return this.checkExpiry(this.session.id)
|
return this.session.id.isValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the current access token valid?
|
* Is the current access token valid?
|
||||||
*/
|
*/
|
||||||
isAccessTokenValid () {
|
isAccessTokenValid () {
|
||||||
return this.checkExpiry(this.session.access)
|
return this.session.access.isValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the user's access token, renewing it if required
|
* Get the user's access token, renewing it if required
|
||||||
*/
|
*/
|
||||||
async getAccessToken () {
|
async getAccessToken (): Promise<string> {
|
||||||
if (this.isAccessTokenValid()) {
|
if (this.isAccessTokenValid()) {
|
||||||
return this.session.access.token
|
return this.session.access.token
|
||||||
} else {
|
} else {
|
||||||
try {
|
const authResult = await this.renewTokens()
|
||||||
const authResult: any = await this.renewTokens()
|
return authResult.accessToken!
|
||||||
return authResult.accessToken
|
|
||||||
} catch (reject) {
|
|
||||||
throw reject
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
25
src/app/src/auth/types.ts
Normal file
25
src/app/src/auth/types.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/** A token and expiration set */
|
||||||
|
export class Token {
|
||||||
|
/** The actual token */
|
||||||
|
token: string = ''
|
||||||
|
|
||||||
|
/** The expiration for the token */
|
||||||
|
expiry: number = 0
|
||||||
|
|
||||||
|
/** Whether this token is currently valid */
|
||||||
|
isValid (): boolean {
|
||||||
|
return this.token !== '' && this.expiry !== 0 && Date.now() < this.expiry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A user's current session */
|
||||||
|
export class Session {
|
||||||
|
/** The user's profile from Auth0 */
|
||||||
|
profile: any = {}
|
||||||
|
|
||||||
|
/** The user's ID token */
|
||||||
|
id = new Token()
|
||||||
|
|
||||||
|
/** The user's access token */
|
||||||
|
access = new Token()
|
||||||
|
}
|
@ -31,7 +31,7 @@ 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'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'journal',
|
name: 'journal',
|
||||||
@ -59,7 +59,7 @@ export default {
|
|||||||
...mapState(['user', 'journal', 'isLoadingJournal'])
|
...mapState(['user', 'journal', 'isLoadingJournal'])
|
||||||
},
|
},
|
||||||
async created () {
|
async created () {
|
||||||
await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress)
|
await this.$store.dispatch(Actions.LoadJournal, this.progress)
|
||||||
this.messages.$emit('info', `Loaded ${this.journal.length} prayer requests`)
|
this.messages.$emit('info', `Loaded ${this.journal.length} prayer requests`)
|
||||||
},
|
},
|
||||||
provide () {
|
provide () {
|
||||||
|
@ -21,7 +21,7 @@ import { mapState } from 'vuex'
|
|||||||
|
|
||||||
import RequestList from '@/components/request/RequestList'
|
import RequestList from '@/components/request/RequestList'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'active-requests',
|
name: 'active-requests',
|
||||||
@ -46,7 +46,7 @@ export default {
|
|||||||
async ensureJournal () {
|
async ensureJournal () {
|
||||||
if (!Array.isArray(this.journal)) {
|
if (!Array.isArray(this.journal)) {
|
||||||
this.loaded = false
|
this.loaded = false
|
||||||
await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress)
|
await this.$store.dispatch(Actions.LoadJournal, this.progress)
|
||||||
}
|
}
|
||||||
this.requests = this.journal
|
this.requests = this.journal
|
||||||
.sort((a, b) => a.showAfter - b.showAfter)
|
.sort((a, b) => a.showAfter - b.showAfter)
|
||||||
|
@ -54,7 +54,7 @@ md-content(role='main').mpj-narrow
|
|||||||
|
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'edit-request',
|
name: 'edit-request',
|
||||||
@ -114,7 +114,7 @@ export default {
|
|||||||
this.title = 'Edit Prayer Request'
|
this.title = 'Edit Prayer Request'
|
||||||
this.isNew = false
|
this.isNew = false
|
||||||
if (this.journal.length === 0) {
|
if (this.journal.length === 0) {
|
||||||
await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress)
|
await this.$store.dispatch(Actions.LoadJournal, this.progress)
|
||||||
}
|
}
|
||||||
const req = this.journal.filter(r => r.requestId === this.id)[0]
|
const req = this.journal.filter(r => r.requestId === this.id)[0]
|
||||||
this.form.requestId = this.id
|
this.form.requestId = this.id
|
||||||
@ -140,12 +140,12 @@ export default {
|
|||||||
},
|
},
|
||||||
async ensureJournal () {
|
async ensureJournal () {
|
||||||
if (!Array.isArray(this.journal)) {
|
if (!Array.isArray(this.journal)) {
|
||||||
await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress)
|
await this.$store.dispatch(Actions.LoadJournal, this.progress)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async saveRequest () {
|
async saveRequest () {
|
||||||
if (this.isNew) {
|
if (this.isNew) {
|
||||||
await this.$store.dispatch(actions.ADD_REQUEST, {
|
await this.$store.dispatch(Actions.AddRequest, {
|
||||||
progress: this.progress,
|
progress: this.progress,
|
||||||
requestText: this.form.requestText,
|
requestText: this.form.requestText,
|
||||||
recurType: this.form.recur.typ === 'Immediate' ? 'Immediate' : this.form.recur.other,
|
recurType: this.form.recur.typ === 'Immediate' ? 'Immediate' : this.form.recur.other,
|
||||||
@ -153,7 +153,7 @@ export default {
|
|||||||
})
|
})
|
||||||
this.messages.$emit('info', 'New prayer request added')
|
this.messages.$emit('info', 'New prayer request added')
|
||||||
} else {
|
} else {
|
||||||
await this.$store.dispatch(actions.UPDATE_REQUEST, {
|
await this.$store.dispatch(Actions.UpdateRequest, {
|
||||||
progress: this.progress,
|
progress: this.progress,
|
||||||
requestId: this.form.requestId,
|
requestId: this.form.requestId,
|
||||||
updateText: this.form.requestText,
|
updateText: this.form.requestText,
|
||||||
|
@ -27,7 +27,7 @@ md-card(v-if='shouldDisplay'
|
|||||||
<script>
|
<script>
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'request-card',
|
name: 'request-card',
|
||||||
@ -47,7 +47,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async markPrayed () {
|
async markPrayed () {
|
||||||
await this.$store.dispatch(actions.UPDATE_REQUEST, {
|
await this.$store.dispatch(Actions.UpdateRequest, {
|
||||||
progress: this.progress,
|
progress: this.progress,
|
||||||
requestId: this.request.requestId,
|
requestId: this.request.requestId,
|
||||||
status: 'Prayed',
|
status: 'Prayed',
|
||||||
|
@ -31,7 +31,7 @@ md-table-row
|
|||||||
<script>
|
<script>
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'request-list-item',
|
name: 'request-list-item',
|
||||||
@ -61,7 +61,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async cancelSnooze () {
|
async cancelSnooze () {
|
||||||
await this.$store.dispatch(actions.SNOOZE_REQUEST, {
|
await this.$store.dispatch(Actions.SnoozeRequest, {
|
||||||
progress: this.progress,
|
progress: this.progress,
|
||||||
requestId: this.request.requestId,
|
requestId: this.request.requestId,
|
||||||
until: 0
|
until: 0
|
||||||
@ -73,7 +73,7 @@ export default {
|
|||||||
this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
|
this.$router.push({ name: 'EditRequest', params: { id: this.request.requestId } })
|
||||||
},
|
},
|
||||||
async showNow () {
|
async showNow () {
|
||||||
await this.$store.dispatch(actions.SHOW_REQUEST_NOW, {
|
await this.$store.dispatch(Actions.ShowRequestNow, {
|
||||||
progress: this.progress,
|
progress: this.progress,
|
||||||
requestId: this.request.requestId,
|
requestId: this.request.requestId,
|
||||||
showAfter: 0
|
showAfter: 0
|
||||||
|
@ -15,7 +15,7 @@ md-dialog(:md-active.sync='snoozeVisible').mpj-skinny
|
|||||||
<script>
|
<script>
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'snooze-request',
|
name: 'snooze-request',
|
||||||
@ -56,7 +56,7 @@ export default {
|
|||||||
this.snoozeVisible = true
|
this.snoozeVisible = true
|
||||||
},
|
},
|
||||||
async snoozeRequest () {
|
async snoozeRequest () {
|
||||||
await this.$store.dispatch(actions.SNOOZE_REQUEST, {
|
await this.$store.dispatch(Actions.SnoozeRequest, {
|
||||||
progress: this.progress,
|
progress: this.progress,
|
||||||
requestId: this.form.requestId,
|
requestId: this.form.requestId,
|
||||||
until: Date.parse(this.form.snoozedUntil)
|
until: Date.parse(this.form.snoozedUntil)
|
||||||
|
@ -19,7 +19,7 @@ article.mpj-main-content(role='main')
|
|||||||
|
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
import actions from '@/store/action-types'
|
import { Actions } from '@/store/types'
|
||||||
|
|
||||||
import RequestList from '@/components/request/RequestList'
|
import RequestList from '@/components/request/RequestList'
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ export default {
|
|||||||
async ensureJournal () {
|
async ensureJournal () {
|
||||||
if (!Array.isArray(this.journal)) {
|
if (!Array.isArray(this.journal)) {
|
||||||
this.loaded = false
|
this.loaded = false
|
||||||
await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress)
|
await this.$store.dispatch(Actions.LoadJournal, this.progress)
|
||||||
}
|
}
|
||||||
this.requests = this.journal
|
this.requests = this.journal
|
||||||
.filter(req => req.snoozedUntil > Date.now())
|
.filter(req => req.snoozedUntil > Date.now())
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
'use strict'
|
import authService from '@/auth'
|
||||||
|
|
||||||
import authService from '../auth/AuthService'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install (Vue) {
|
install (Vue) {
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
/* eslint-disable */
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Router from 'vue-router'
|
import Router from 'vue-router'
|
||||||
|
|
||||||
import auth from './auth/AuthService'
|
import auth from '@/auth'
|
||||||
import Home from '@/components/Home.vue'
|
import Home from '@/components/Home.vue'
|
||||||
/* eslint-enable */
|
|
||||||
|
|
||||||
Vue.use(Router)
|
Vue.use(Router)
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
/** Action to add a prayer request (pass request text) */
|
|
||||||
ADD_REQUEST: 'add-request',
|
|
||||||
/** Action to check if a user is authenticated, refreshing the session first if it exists */
|
|
||||||
CHECK_AUTHENTICATION: 'check-authentication',
|
|
||||||
/** Action to load the user's prayer journal */
|
|
||||||
LOAD_JOURNAL: 'load-journal',
|
|
||||||
/** Action to update a request */
|
|
||||||
UPDATE_REQUEST: 'update-request',
|
|
||||||
/** Action to skip the remaining recurrence period */
|
|
||||||
SHOW_REQUEST_NOW: 'show-request-now',
|
|
||||||
/** Action to snooze a request */
|
|
||||||
SNOOZE_REQUEST: 'snooze-request'
|
|
||||||
}
|
|
@ -1,20 +1,15 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
/* eslint-disable no-multi-spaces */
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex, { StoreOptions } from 'vuex'
|
||||||
|
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import auth from '@/auth/AuthService'
|
import auth from '@/auth'
|
||||||
|
|
||||||
import mutations from './mutation-types'
|
import { AppState, Actions, JournalRequest, Mutations } from './types'
|
||||||
import actions from './action-types'
|
|
||||||
/* eslint-enable no-multi-spaces */
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
const logError = function (error) {
|
const logError = function (error: any) { // TODO: can we do better on this type?
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
// The request was made and the server responded with a status code
|
// The request was made and the server responded with a status code
|
||||||
// that falls out of the range of 2xx
|
// that falls out of the range of 2xx
|
||||||
@ -41,7 +36,7 @@ const setBearer = async function () {
|
|||||||
await auth.getAccessToken()
|
await auth.getAccessToken()
|
||||||
api.setBearer(auth.session.id.token)
|
api.setBearer(auth.session.id.token)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err === 'Not logged in') {
|
if (err.message === 'Not logged in') {
|
||||||
console.warn('API request attempted when user was not logged in')
|
console.warn('API request attempted when user was not logged in')
|
||||||
} else {
|
} else {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
@ -54,88 +49,87 @@ const setBearer = async function () {
|
|||||||
* Get the sort value for a prayer request
|
* Get the sort value for a prayer request
|
||||||
* @param x The prayer request
|
* @param x The prayer request
|
||||||
*/
|
*/
|
||||||
const sortValue = x => x.showAfter === 0 ? x.asOf : x.showAfter
|
const sortValue = (x: JournalRequest) => x.showAfter === 0 ? x.asOf : x.showAfter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort journal requests either by asOf or showAfter
|
* Sort journal requests either by asOf or showAfter
|
||||||
*/
|
*/
|
||||||
const journalSort = (a, b) => sortValue(a) - sortValue(b)
|
const journalSort = (a: JournalRequest, b: JournalRequest) => sortValue(a) - sortValue(b)
|
||||||
|
|
||||||
const emptyJournal: any = []
|
/** The initial state of the store */
|
||||||
|
const store : StoreOptions<AppState> = {
|
||||||
export default new Vuex.Store({
|
|
||||||
state: {
|
state: {
|
||||||
user: auth.session.profile,
|
user: auth.session.profile,
|
||||||
isAuthenticated: auth.isAuthenticated(),
|
isAuthenticated: auth.isAuthenticated(),
|
||||||
journal: emptyJournal,
|
journal: [],
|
||||||
isLoadingJournal: false
|
isLoadingJournal: false
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
[mutations.LOADING_JOURNAL] (state, flag) {
|
[Mutations.LoadingJournal] (state, flag: boolean) {
|
||||||
state.isLoadingJournal = flag
|
state.isLoadingJournal = flag
|
||||||
},
|
},
|
||||||
[mutations.LOADED_JOURNAL] (state, journal) {
|
[Mutations.LoadedJournal] (state, journal: JournalRequest[]) {
|
||||||
state.journal = journal.sort(journalSort)
|
state.journal = journal.sort(journalSort)
|
||||||
},
|
},
|
||||||
[mutations.REQUEST_ADDED] (state, newRequest) {
|
[Mutations.RequestAdded] (state, newRequest: JournalRequest) {
|
||||||
state.journal.push(newRequest)
|
state.journal.push(newRequest)
|
||||||
},
|
},
|
||||||
[mutations.REQUEST_UPDATED] (state, request) {
|
[Mutations.RequestUpdated] (state, request: JournalRequest) {
|
||||||
const jrnl = state.journal.filter(it => it.requestId !== request.requestId)
|
const jrnl = state.journal.filter(it => it.requestId !== request.requestId)
|
||||||
if (request.lastStatus !== 'Answered') jrnl.push(request)
|
if (request.lastStatus !== 'Answered') jrnl.push(request)
|
||||||
state.journal = jrnl
|
state.journal = jrnl
|
||||||
},
|
},
|
||||||
[mutations.SET_AUTHENTICATION] (state, value) {
|
[Mutations.SetAuthentication] (state, value: boolean) {
|
||||||
state.isAuthenticated = value
|
state.isAuthenticated = value
|
||||||
},
|
},
|
||||||
[mutations.USER_LOGGED_OFF] (state) {
|
[Mutations.UserLoggedOff] (state) {
|
||||||
state.user = {}
|
state.user = {}
|
||||||
api.removeBearer()
|
api.removeBearer()
|
||||||
state.isAuthenticated = false
|
state.isAuthenticated = false
|
||||||
},
|
},
|
||||||
[mutations.USER_LOGGED_ON] (state, user) {
|
[Mutations.UserLoggedOn] (state, user) {
|
||||||
state.user = user
|
state.user = user
|
||||||
state.isAuthenticated = true
|
state.isAuthenticated = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async [actions.ADD_REQUEST] ({ commit }, { progress, requestText, recurType, recurCount }) {
|
async [Actions.AddRequest] ({ commit }, { progress, requestText, recurType, recurCount }) {
|
||||||
progress.$emit('show', 'indeterminate')
|
progress.$emit('show', 'indeterminate')
|
||||||
try {
|
try {
|
||||||
await setBearer()
|
await setBearer()
|
||||||
const newRequest = await api.addRequest(requestText, recurType, recurCount)
|
const newRequest = await api.addRequest(requestText, recurType, recurCount)
|
||||||
commit(mutations.REQUEST_ADDED, newRequest.data)
|
commit(Mutations.RequestAdded, newRequest.data)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logError(err)
|
logError(err)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async [actions.CHECK_AUTHENTICATION] ({ commit }) {
|
async [Actions.CheckAuthentication] ({ commit }) {
|
||||||
try {
|
try {
|
||||||
await auth.getAccessToken()
|
await auth.getAccessToken()
|
||||||
commit(mutations.SET_AUTHENTICATION, auth.isAuthenticated())
|
commit(Mutations.SetAuthentication, auth.isAuthenticated())
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
commit(mutations.SET_AUTHENTICATION, false)
|
commit(Mutations.SetAuthentication, false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async [actions.LOAD_JOURNAL] ({ commit }, progress) {
|
async [Actions.LoadJournal] ({ commit }, progress) {
|
||||||
commit(mutations.LOADED_JOURNAL, [])
|
commit(Mutations.LoadedJournal, [])
|
||||||
progress.$emit('show', 'query')
|
progress.$emit('show', 'query')
|
||||||
commit(mutations.LOADING_JOURNAL, true)
|
commit(Mutations.LoadingJournal, true)
|
||||||
await setBearer()
|
await setBearer()
|
||||||
try {
|
try {
|
||||||
const jrnl = await api.journal()
|
const jrnl = await api.journal()
|
||||||
commit(mutations.LOADED_JOURNAL, jrnl.data)
|
commit(Mutations.LoadedJournal, jrnl.data)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logError(err)
|
logError(err)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
} finally {
|
} finally {
|
||||||
commit(mutations.LOADING_JOURNAL, false)
|
commit(Mutations.LoadingJournal, false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async [actions.UPDATE_REQUEST] ({ commit, state }, { progress, requestId, status, updateText, recurType, recurCount }) {
|
async [Actions.UpdateRequest] ({ commit, state }, { progress, requestId, status, updateText, recurType, recurCount }) {
|
||||||
progress.$emit('show', 'indeterminate')
|
progress.$emit('show', 'indeterminate')
|
||||||
try {
|
try {
|
||||||
await setBearer()
|
await setBearer()
|
||||||
@ -149,33 +143,33 @@ export default new Vuex.Store({
|
|||||||
await api.updateRequest(requestId, status, oldReq.text !== updateText ? updateText : '')
|
await api.updateRequest(requestId, status, oldReq.text !== updateText ? updateText : '')
|
||||||
}
|
}
|
||||||
const request = await api.getRequest(requestId)
|
const request = await api.getRequest(requestId)
|
||||||
commit(mutations.REQUEST_UPDATED, request.data)
|
commit(Mutations.RequestUpdated, request.data)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logError(err)
|
logError(err)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async [actions.SHOW_REQUEST_NOW] ({ commit }, { progress, requestId, showAfter }) {
|
async [Actions.ShowRequestNow] ({ commit }, { progress, requestId, showAfter }) {
|
||||||
progress.$emit('show', 'indeterminate')
|
progress.$emit('show', 'indeterminate')
|
||||||
try {
|
try {
|
||||||
await setBearer()
|
await setBearer()
|
||||||
await api.showRequest(requestId, showAfter)
|
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.RequestUpdated, request.data)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logError(err)
|
logError(err)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async [actions.SNOOZE_REQUEST] ({ commit }, { progress, requestId, until }) {
|
async [Actions.SnoozeRequest] ({ commit }, { progress, requestId, until }) {
|
||||||
progress.$emit('show', 'indeterminate')
|
progress.$emit('show', 'indeterminate')
|
||||||
try {
|
try {
|
||||||
await setBearer()
|
await setBearer()
|
||||||
await api.snoozeRequest(requestId, until)
|
await api.snoozeRequest(requestId, until)
|
||||||
const request = await api.getRequest(requestId)
|
const request = await api.getRequest(requestId)
|
||||||
commit(mutations.REQUEST_UPDATED, request.data)
|
commit(Mutations.RequestUpdated, request.data)
|
||||||
progress.$emit('done')
|
progress.$emit('done')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logError(err)
|
logError(err)
|
||||||
@ -185,4 +179,6 @@ export default new Vuex.Store({
|
|||||||
},
|
},
|
||||||
getters: {},
|
getters: {},
|
||||||
modules: {}
|
modules: {}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
export default new Vuex.Store<AppState>(store)
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
/** Mutation for when the user's prayer journal is being loaded */
|
|
||||||
LOADING_JOURNAL: 'loading-journal',
|
|
||||||
/** Mutation for when the user's prayer journal has been loaded */
|
|
||||||
LOADED_JOURNAL: 'journal-loaded',
|
|
||||||
/** Mutation for adding a new prayer request (pass text) */
|
|
||||||
REQUEST_ADDED: 'request-added',
|
|
||||||
/** Mutation to replace a prayer request at the top of the current journal */
|
|
||||||
REQUEST_UPDATED: 'request-updated',
|
|
||||||
/** Mutation for setting the authentication state */
|
|
||||||
SET_AUTHENTICATION: 'set-authentication',
|
|
||||||
/** Mutation for logging a user off */
|
|
||||||
USER_LOGGED_OFF: 'user-logged-off',
|
|
||||||
/** Mutation for logging a user on (pass user) */
|
|
||||||
USER_LOGGED_ON: 'user-logged-on'
|
|
||||||
}
|
|
95
src/app/src/store/types.ts
Normal file
95
src/app/src/store/types.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/** A prayer request that is part of the user's journal */
|
||||||
|
export interface JournalRequest {
|
||||||
|
/** The ID of the request (just the CUID part) */
|
||||||
|
requestId: string
|
||||||
|
|
||||||
|
/** The ID of the user to whom the request belongs */
|
||||||
|
userId: string
|
||||||
|
|
||||||
|
/** The current text of the request */
|
||||||
|
text: string
|
||||||
|
|
||||||
|
/** The last time action was taken on the request */
|
||||||
|
asOf: number
|
||||||
|
|
||||||
|
/** The last status for the request */
|
||||||
|
lastStatus: string // TODO string union?
|
||||||
|
|
||||||
|
/** The time that this request should reappear in the user's journal */
|
||||||
|
snoozedUntil: number
|
||||||
|
|
||||||
|
/** The time after which this request should reappear in the user's journal by configured recurrence */
|
||||||
|
showAfter: number
|
||||||
|
|
||||||
|
/** The type of recurrence for this request */
|
||||||
|
recurType: string // TODO Recurrence union?
|
||||||
|
|
||||||
|
/** How many of the recurrence intervals should occur between appearances in the journal */
|
||||||
|
recurCount: number
|
||||||
|
|
||||||
|
/** History entries for the request */
|
||||||
|
history: any[] // History list
|
||||||
|
|
||||||
|
/** Note entries for the request */
|
||||||
|
notes: any[] // Note list
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The state of myPrayerJournal */
|
||||||
|
export interface AppState {
|
||||||
|
/** The user's profile */
|
||||||
|
user: any,
|
||||||
|
|
||||||
|
/** Whether there is a user signed in */
|
||||||
|
isAuthenticated: boolean,
|
||||||
|
|
||||||
|
/** The current set of prayer requests */
|
||||||
|
journal: JournalRequest[],
|
||||||
|
|
||||||
|
/** Whether the journal is currently being loaded */
|
||||||
|
isLoadingJournal: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
/** Action to add a prayer request (pass request text) */
|
||||||
|
AddRequest: 'add-request',
|
||||||
|
|
||||||
|
/** Action to check if a user is authenticated, refreshing the session first if it exists */
|
||||||
|
CheckAuthentication: 'check-authentication',
|
||||||
|
|
||||||
|
/** Action to load the user's prayer journal */
|
||||||
|
LoadJournal: 'load-journal',
|
||||||
|
|
||||||
|
/** Action to update a request */
|
||||||
|
UpdateRequest: 'update-request',
|
||||||
|
|
||||||
|
/** Action to skip the remaining recurrence period */
|
||||||
|
ShowRequestNow: 'show-request-now',
|
||||||
|
|
||||||
|
/** Action to snooze a request */
|
||||||
|
SnoozeRequest: 'snooze-request'
|
||||||
|
}
|
||||||
|
export { actions as Actions }
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
/** Mutation for when the user's prayer journal is being loaded */
|
||||||
|
LoadingJournal: 'loading-journal',
|
||||||
|
|
||||||
|
/** Mutation for when the user's prayer journal has been loaded */
|
||||||
|
LoadedJournal: 'journal-loaded',
|
||||||
|
|
||||||
|
/** Mutation for adding a new prayer request (pass text) */
|
||||||
|
RequestAdded: 'request-added',
|
||||||
|
|
||||||
|
/** Mutation to replace a prayer request at the top of the current journal */
|
||||||
|
RequestUpdated: 'request-updated',
|
||||||
|
|
||||||
|
/** Mutation for setting the authentication state */
|
||||||
|
SetAuthentication: 'set-authentication',
|
||||||
|
|
||||||
|
/** Mutation for logging a user off */
|
||||||
|
UserLoggedOff: 'user-logged-off',
|
||||||
|
|
||||||
|
/** Mutation for logging a user on (pass user) */
|
||||||
|
UserLoggedOn: 'user-logged-on'
|
||||||
|
}
|
||||||
|
export { mutations as Mutations }
|
Loading…
Reference in New Issue
Block a user