Conversion to cards (bootstrap) complete

Also:
- Multi-line requests now preserve line breaks (#7)
- Have one instance of vue-toast; access via $parent for main page
components, pass to child components
This commit is contained in:
Daniel J. Summers 2017-09-30 12:36:57 -05:00
parent ef88964cd0
commit 834eaf2416
6 changed files with 94 additions and 80 deletions

View File

@ -4,6 +4,7 @@
#content.container #content.container
router-view router-view
vue-progress-bar vue-progress-bar
toast(ref='toast')
footer footer
p.text-right: i myPrayerJournal v0.8.1 p.text-right: i myPrayerJournal v0.8.1
</template> </template>
@ -17,6 +18,14 @@ export default {
name: 'app', name: 'app',
components: { components: {
Navigation Navigation
},
mounted () {
this.$refs.toast.setOptions({ position: 'bottom right' })
},
computed: {
toast () {
return this.$refs.toast
}
} }
} }
</script> </script>

View File

@ -1,21 +1,30 @@
<template lang="pug"> <template lang="pug">
article article
page-title(:title='title') page-title(:title='title')
toast(ref='toast')
p(v-if='isLoadingJournal') Loading your prayer journal... p(v-if='isLoadingJournal') Loading your prayer journal...
template(v-if='!isLoadingJournal') template(v-if='!isLoadingJournal')
new-request new-request
br br
b-row request-list-item(v-if='journal.length > 0'
request-list-item(v-if='journal.length > 0' v-for='request in journal' :request='request' :key='request.requestId') v-for='row in journalCardRows'
:row='row'
:events='eventBus'
:toast='toast'
:key='row[0].requestId')
p.text-center(v-if='journal.length === 0'): em No requests found; click the "Add a New Request" button to add one p.text-center(v-if='journal.length === 0'): em No requests found; click the "Add a New Request" button to add one
edit-request(:events='eventBus' :toast='toast' )
full-request(:events='eventBus')
</template> </template>
<script> <script>
'use strict' 'use strict'
import Vue from 'vue'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import _ from 'lodash'
import EditRequest from './request/EditRequest'
import FullRequest from './request/FullRequest'
import NewRequest from './request/NewRequest' import NewRequest from './request/NewRequest'
import RequestListItem from './request/RequestListItem' import RequestListItem from './request/RequestListItem'
@ -23,7 +32,14 @@ import actions from '@/store/action-types'
export default { export default {
name: 'journal', name: 'journal',
data () {
return {
eventBus: new Vue()
}
},
components: { components: {
EditRequest,
FullRequest,
NewRequest, NewRequest,
RequestListItem RequestListItem
}, },
@ -31,18 +47,17 @@ export default {
title () { title () {
return `${this.user.given_name}'s Prayer Journal` return `${this.user.given_name}'s Prayer Journal`
}, },
journalCardRows () {
return _.chunk(this.journal, 3)
},
toast () {
return this.$parent.$refs.toast
},
...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.LOAD_JOURNAL, this.$Progress)
this.$refs.toast.setOptions({ position: 'bottom right' }) this.toast.showToast(`Loaded ${this.journal.length} prayer requests`, { theme: 'success' })
this.$refs.toast.showToast(`Loaded ${this.journal.length} prayer requests`, { theme: 'success' })
} }
} }
/*
b-row
b-col(cols='2'): strong Actions
b-col(cols='8'): strong Request
b-col(cols='2'): strong As Of
*/
</script> </script>

View File

@ -22,7 +22,6 @@ export default {
data () { data () {
const dt = moment(this.value) const dt = moment(this.value)
return { return {
dt,
fromNow: dt.fromNow(), fromNow: dt.fromNow(),
actual: dt.format('LLLL'), actual: dt.format('LLLL'),
intervalId: null intervalId: null
@ -37,7 +36,7 @@ export default {
}, },
methods: { methods: {
updateFromNow () { updateFromNow () {
let newFromNow = this.dt.fromNow() let newFromNow = moment(this.value).fromNow()
if (newFromNow !== this.fromNow) this.fromNow = newFromNow if (newFromNow !== this.fromNow) this.fromNow = newFromNow
} }
}, },

View File

@ -1,11 +1,12 @@
<template lang="pug"> <template lang="pug">
span span
b-btn(@click='openDialog()' title='Edit' size='sm' variant='outline-secondary'): icon(name='pencil') //- b-btn(@click='openDialog()' title='Edit' size='sm' variant='outline-secondary'): icon(name='pencil')
b-modal(title='Edit Prayer Request' b-modal(title='Edit Prayer Request'
v-model='editVisible' v-model='editVisible'
size='lg' size='lg'
header-bg-variant='dark' header-bg-variant='dark'
header-text-variant='light' header-text-variant='light'
@edit='openDialog()'
@shows='focusRequestText') @shows='focusRequestText')
b-form b-form
b-form-group(label='Prayer Request' label-for='request_text') b-form-group(label='Prayer Request' label-for='request_text')
@ -19,7 +20,6 @@ span
b-btn(variant='primary' @click='saveRequest()') Save b-btn(variant='primary' @click='saveRequest()') Save
| &nbsp; &nbsp; | &nbsp; &nbsp;
b-btn(variant='outline-secondary' @click='closeDialog()') Cancel b-btn(variant='outline-secondary' @click='closeDialog()') Cancel
toast(ref='toast')
</template> </template>
<script> <script>
@ -30,23 +30,25 @@ import actions from '@/store/action-types'
export default { export default {
name: 'edit-request', name: 'edit-request',
props: { props: {
request: { required: true } toast: { required: true },
events: { required: true }
}, },
data () { data () {
return { return {
editVisible: false, editVisible: false,
form: { form: {
requestText: this.request.text, requestId: '',
requestText: '',
status: 'Updated' status: 'Updated'
}, }
formLabelWidth: '120px'
} }
}, },
mounted () { created () {
this.$refs.toast.setOptions({ position: 'bottom right' }) this.events.$on('edit', this.openDialog)
}, },
methods: { methods: {
closeDialog () { closeDialog () {
this.form.requestId = ''
this.form.requestText = '' this.form.requestText = ''
this.form.status = 'Updated' this.form.status = 'Updated'
this.editVisible = false this.editVisible = false
@ -54,8 +56,11 @@ export default {
focusRequestText (e) { focusRequestText (e) {
this.$refs.toFocus.focus() this.$refs.toFocus.focus()
}, },
openDialog () { openDialog (request) {
this.form.requestId = request.requestId
this.form.requestText = request.text
this.editVisible = true this.editVisible = true
this.focusRequestText(null)
}, },
trimText () { trimText () {
this.form.requestText = this.form.requestText.trim() this.form.requestText = this.form.requestText.trim()
@ -63,17 +68,17 @@ export default {
async saveRequest () { async saveRequest () {
await this.$store.dispatch(actions.UPDATE_REQUEST, { await this.$store.dispatch(actions.UPDATE_REQUEST, {
progress: this.$Progress, progress: this.$Progress,
requestId: this.request.requestId, requestId: this.form.requestId,
updateText: this.form.requestText, updateText: this.form.requestText,
status: this.form.status status: this.form.status
}) })
if (this.form.status === 'Answered') { if (this.form.status === 'Answered') {
this.$refs.toast.showToast('Request updated and removed from active journal', { theme: 'success' }) this.toast.showToast('Request updated and removed from active journal', { theme: 'success' })
} else { } else {
this.$refs.toast.showToast('Request updated', { theme: 'success' }) this.toast.showToast('Request updated', { theme: 'success' })
} }
this.editVisible = false this.closeDialog()
} }
} }
} }
</script> </script>

View File

@ -23,7 +23,7 @@ import api from '@/api'
export default { export default {
name: 'full-request', name: 'full-request',
props: { props: {
request: { required: true } events: { required: true }
}, },
data () { data () {
return { return {
@ -31,6 +31,9 @@ export default {
full: null full: null
} }
}, },
created () {
this.events.$on('full', this.openDialog)
},
components: { components: {
FullRequestHistory FullRequestHistory
}, },
@ -39,10 +42,10 @@ export default {
this.full = null this.full = null
this.historyVisible = false this.historyVisible = false
}, },
async openDialog () { async openDialog (requestId) {
this.historyVisible = true this.historyVisible = true
this.$Progress.start() this.$Progress.start()
const req = await api.getFullRequest(this.request.requestId) const req = await api.getFullRequest(requestId)
this.full = req.data this.full = req.data
this.$Progress.finish() this.$Progress.finish()
} }

View File

@ -1,74 +1,57 @@
<template lang="pug"> <template lang="pug">
b-col(xs='12' sm='6' md='4') div
b-card(border-variant='dark' no-body) b-card-group.w-100(deck)
div.card-body.p-0 b-card(v-for='(request, idx) in row' border-variant='dark' no-body)
p.card-text.mb-1.px-3.pt-3 b-card-body.p-0
| {{ text }} p.card-text.request-card-text.mb-1.px-3.pt-3
p.card-text.p-0.pr-1.text-right: small.text-muted: em | {{ request.text }}
= '(last activity ' p.card-text.p-0.pr-1.text-right: small.text-muted: em
date-from-now(:value='request.asOf') = '(last activity '
| ) date-from-now(:value='request.asOf')
//- | )
edit-request(:request='request') b-card-footer.text-center.py-1.
full-request(:request='request') #[b-btn(@click='markPrayed(idx)' variant='outline-primary' title='Pray' size='sm'): icon(name='check')]
b-card-footer.text-center.py-1. #[b-btn(@click.stop='showEdit(request)' variant='outline-secondary' title='Edit' size='sm'): icon(name='pencil')]
#[b-btn(@click='markPrayed()' variant='outline-primary' title='Pray' size='sm'): icon(name='check')] #[b-btn(disabled variant='outline-secondary' title='Add Notes' size='sm'): icon(name='file-text-o')]
#[b-btn(variant='outline-secondary' title='Edit' size='sm'): icon(name='pencil')] #[b-btn(@click.stop='showFull(idx)' variant='outline-secondary' title='View Full Request' size='sm'): icon(name='search')]
#[b-btn(variant='outline-secondary' title='Add Notes' size='sm'): icon(name='file-text-o')] b-card(v-for='it in 3 - row.length')
#[b-btn(variant='outline-secondary' title='View Full Request' size='sm'): icon(name='search')]
br br
toast(ref='toast')
</template> </template>
<script> <script>
'use strict' 'use strict'
import moment from 'moment'
import EditRequest from './EditRequest'
import FullRequest from './FullRequest'
import actions from '@/store/action-types' import actions from '@/store/action-types'
export default { export default {
name: 'request-list-item', name: 'request-list-item',
props: { props: {
request: { required: true } row: { required: true },
}, toast: { required: true },
components: { events: { required: true }
EditRequest,
FullRequest
},
mounted () {
this.$refs.toast.setOptions({ position: 'bottom right' })
}, },
methods: { methods: {
async markPrayed () { async markPrayed (idx) {
await this.$store.dispatch(actions.UPDATE_REQUEST, { await this.$store.dispatch(actions.UPDATE_REQUEST, {
progress: this.$Progress, progress: this.$Progress,
requestId: this.request.requestId, requestId: this.row[idx].requestId,
status: 'Prayed', status: 'Prayed',
updateText: '' updateText: ''
}) })
this.$refs.toast.showToast('Request marked as prayed', { theme: 'success' }) this.toast.showToast('Request marked as prayed', { theme: 'success' })
}
},
computed: {
asOf () {
return moment(this.request.asOf).fromNow()
}, },
text () { showEdit (request) {
return this.request.text.split('\n').join('<br>') this.events.$emit('edit', request)
},
showFull (idx) {
this.events.$emit('full', this.row[idx].requestId)
} }
} }
} }
/*
b-row.journal-request
b-col(cols='2'): p
b-btn(@click='markPrayed()' size='sm' variant='outline-primary' title='Pray'): icon(name='check')
edit-request(:request='request')
full-request(:request='request')
b-col(cols='8'): p {{ text }}
b-col(cols='2'): p: date-from-now(:value='request.asOf')
*/
</script> </script>
<style>
.request-card-text {
white-space: pre-line;
}
</style>