Skip to content
This repository has been archived by the owner on Jul 7, 2023. It is now read-only.

Commit

Permalink
Merge pull request #28 from BenShelton/develop
Browse files Browse the repository at this point in the history
Support for Assembly Weeks
  • Loading branch information
BenShelton authored Jan 25, 2019
2 parents cc66300 + a4d0c70 commit 0accbd8
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 38 deletions.
46 changes: 43 additions & 3 deletions database/schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import assert from 'assert'
import setup from './setup'
import scrapeWOL from './scraper'
import { addAssignment, removeAssignment } from './congregation'
import { WEEK_TYPES } from '../src/constants'

const ASSIGNEE_FIELDS = ['assignee', 'assistant']

const getCollection = new Promise(resolve => {
setup
Expand Down Expand Up @@ -54,7 +57,6 @@ export const scrapeWeek = async ({ weekID }) => {
}

export const updateAssignment = async ({ weekID, name, assignment }) => {
const assigneeFields = ['assignee', 'assistant']
const coll = await getCollection
const query = { _id: ObjectID(weekID) }

Expand All @@ -64,7 +66,7 @@ export const updateAssignment = async ({ weekID, name, assignment }) => {
assert.notStrictEqual(null, week, 404)
const previousAssignment = week.assignments[name]
if (previousAssignment) {
for (const field of assigneeFields) {
for (const field of ASSIGNEE_FIELDS) {
const memberID = previousAssignment[field]
if (memberID) {
const member = await removeAssignment({ memberID, assignment: { type: previousAssignment.type, date: week.date } })
Expand All @@ -81,7 +83,7 @@ export const updateAssignment = async ({ weekID, name, assignment }) => {
assert.notStrictEqual(null, value, 404)

// Add newly assigned members
for (const field of assigneeFields) {
for (const field of ASSIGNEE_FIELDS) {
const memberID = value.assignments[name][field]
if (memberID) {
const member = await addAssignment({ memberID, assignment: { type: assignment.type, date: value.date } })
Expand All @@ -92,3 +94,41 @@ export const updateAssignment = async ({ weekID, name, assignment }) => {
// Return assignment
return { week: value, members: updatedMembers }
}

export const updateWeekType = async ({ weekID, type }) => {
const coll = await getCollection
const query = { _id: ObjectID(weekID) }

// Check the previous week didn't already have the same type
const week = await coll.findOne(query)
assert.notStrictEqual(null, week, 404)
assert.notStrictEqual(type, week.type, 400)

// Remove existing assigned members if necessary
const update = { $set: {} }
const updatedMembers = []
switch (type) {
case WEEK_TYPES.assembly.value:
for (const [k, v] of Object.entries(week.assignments || {})) {
if (v) {
for (const field of ASSIGNEE_FIELDS) {
const memberID = v[field]
if (memberID) {
const member = await removeAssignment({ memberID, assignment: { type: v.type, date: week.date } })
updatedMembers.push(member)
const assignmentPath = `assignments.${k}.${field}`
update.$set[assignmentPath] = null
}
}
}
}
}

// Update Type
Object.assign(update.$set, { type })
const { value } = await coll.findOneAndUpdate(query, update, { returnOriginal: false })
assert.notStrictEqual(null, value, 404)

// Return week and any removed assigned members
return { week: value, members: updatedMembers }
}
11 changes: 10 additions & 1 deletion lambda/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const serverless = require('serverless-http')
const auth = require('../database/auth')
const congregation = require('../database/congregation')
const schedule = require('../database/schedule')
const { APPOINTMENTS, GENDERS, LANGUAGE_GROUPS } = require('../src/constants')
const { APPOINTMENTS, GENDERS, LANGUAGE_GROUPS, WEEK_TYPES } = require('../src/constants')

// Initialize express app
const app = express()
Expand Down Expand Up @@ -135,6 +135,15 @@ router.put('/schedule/updateAssignment', (req, res) => {
.catch(handleErrors(res))
})

router.put('/schedule/updateWeekType', (req, res) => {
const { weekID, type } = req.body
if (!weekID || type === undefined) return res.status(400).json({ message: 'Required Fields are: weekID, type' })
if (!(Object.values(WEEK_TYPES).some(t => t.value === type))) return res.status(400).json({ message: 'Invalid Type' })
schedule.updateWeekType({ weekID, type })
.then(returnResult(res))
.catch(handleErrors(res))
})

// The lambda function route must match the netlify path
app.use('/.netlify/functions/api', router)
app.use((req, res) => {
Expand Down
3 changes: 2 additions & 1 deletion src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export default {
week: ({ date }) => api.get(`/schedule/week/${date}`),
month: ({ month }) => api.get(`/schedule/month/${month}`),
scrape: ({ weekID }) => api.put(`/schedule/scrape/`, { weekID }),
updateAssignment: ({ weekID, name, assignment }) => api.put(`/schedule/updateAssignment`, { weekID, name, assignment })
updateAssignment: ({ weekID, name, assignment }) => api.put(`/schedule/updateAssignment`, { weekID, name, assignment }),
updateWeekType: ({ weekID, type }) => api.put(`/schedule/updateWeekType`, { weekID, type })
}
}
1 change: 1 addition & 0 deletions src/components/AssigneeSelect.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<VSelect
clearable
item-text="name"
item-value="_id"
no-data-text="No Assignees Available"
Expand Down
126 changes: 95 additions & 31 deletions src/components/Schedule/ScheduleWeek.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,51 @@
<VToolbar :color="toolbarColor">
<VToolbarTitle v-text="prettyDate" />
<VSpacer />
<VMenu v-if="week && week.scraped" offset-y>
<VBtn
slot="activator"
flat
icon
>
<VMenu
v-if="week.loaded"
v-model="settingsMenu"
lazy
left
offset-y
:close-on-content-click="false"
>
<VBtn slot="activator" flat icon>
<VIcon>settings</VIcon>
</VBtn>
<VList>
<VListTile @click="onRedownload">
<VListTileTitle>Redownload</VListTileTitle>
</VListTile>
</VList>
<VCard class="pa-3">
<VBtn
color="primary"
:loading="scrapeLoading"
:disabled="scrapeLoading"
@click="onScrape"
>
Redownload
<VIcon right>
cloud_download
</VIcon>
</VBtn>
<VDivider class="mt-3" />
<VRadioGroup
v-model="weekType"
hide-details
label="Week Type"
:disabled="weekTypeLoading"
>
<VRadio
v-for="type in WEEK_TYPES"
:key="type.value"
class="ml-3"
:ripple="false"
:label="type.label"
:value="type.value"
/>
</VRadioGroup>
</VCard>
</Vmenu>
</VToolbar>

<!-- Loading Week Display -->
<VLayout v-if="!week" justify-center class="pa-3">
<VLayout v-if="!week.loaded" justify-center class="pa-3">
<VLayout v-if="loadError" column align-center>
<VIcon color="red">
warning
Expand Down Expand Up @@ -68,6 +95,18 @@
</VLayout>
</VLayout>

<!-- Assembly Week Display -->
<VLayout v-else-if="week.type === WEEK_TYPES.assembly.value" justify-center class="pa-3">
<VLayout column align-center>
<VIcon large color="primary">
group
</VIcon>
<p class="headline text-xs-center primary--text mt-3">
Assembly Week
</p>
</VLayout>
</VLayout>

<!-- Assignment Display -->
<VList
v-else
Expand Down Expand Up @@ -219,7 +258,7 @@ import ScheduleSection from '@/components/Schedule/ScheduleSection'
import ScheduleAssignment from '@/components/Schedule/ScheduleAssignment'
import AssigneeSelect from '@/components/AssigneeSelect'
import { ASSIGNMENT_TYPE_MAP } from '@/constants'
import { ASSIGNMENT_TYPE_MAP, WEEK_TYPES } from '@/constants'
export default {
name: 'ScheduleWeek',
Expand All @@ -241,7 +280,7 @@ export default {
return
}
this.loadWeek({ date: this.weekDate })
.then(week => { this.week = week })
.then(this.loadLocalWeek)
.catch(err => {
this.loadError = true
console.error(err)
Expand All @@ -250,10 +289,13 @@ export default {
data () {
return {
week: null,
WEEK_TYPES,
week: { type: 0, loaded: false },
loadError: false,
scrapeLoading: false,
scrapeError: false,
settingsMenu: false,
weekTypeLoading: false,
editDialog: false,
editName: '',
editTitle: '',
Expand All @@ -263,6 +305,35 @@ export default {
},
computed: {
weekType: {
get () {
return this.week.type || 0
},
set (val) {
const prev = this.weekType
this.week.type = val
// wait for the animation to finish
setTimeout(() => {
if (!window.confirm('Are you sure you want to change the week type? All items may be unassigned.')) {
this.week.type = prev
return
}
this.weekTypeLoading = true
this.updateWeekType({ weekID: this.week._id, type: val })
.then(this.loadLocalWeek)
.then(() => {
this.alert({ text: 'Week Type successfully updated', color: 'success' })
this.settingsMenu = false
})
.catch(err => {
this.week.type = prev
this.alert({ text: 'Week Type could not be toggled', color: 'error' })
console.error(err)
})
.finally(() => { this.weekTypeLoading = false })
}, 100)
}
},
toolbarColor () {
return this.current ? 'primary' : 'grey'
},
Expand Down Expand Up @@ -306,28 +377,23 @@ export default {
...mapActions({
loadWeek: 'schedule/loadWeek',
scrapeWeek: 'schedule/scrapeWeek',
updateAssignment: 'schedule/updateAssignment'
updateAssignment: 'schedule/updateAssignment',
updateWeekType: 'schedule/updateWeekType'
}),
...mapMutations({
alert: 'alert/UPDATE_ALERT'
}),
onRedownload () {
this.scrapeWeek({ weekID: this.week._id })
.then(week => {
this.week = week
this.alert({ text: 'Week successfully redownloaded', color: 'success' })
})
.catch(err => {
this.alert({ text: 'Week could not be redownloaded', color: 'error' })
console.error(err)
})
loadLocalWeek (week) {
this.week = Object.assign({}, { loaded: true }, week)
},
onScrape () {
this.scrapeLoading = true
this.scrapeWeek({ weekID: this.week._id })
.then(week => { this.week = week })
.then(this.loadLocalWeek)
.then(() => this.alert({ text: 'Week successfully downloaded', color: 'success' }))
.catch(err => {
this.scrapeError = true
this.alert({ text: 'Week could not be downloaded', color: 'error' })
console.error(err)
})
.finally(() => { this.scrapeLoading = false })
Expand All @@ -351,10 +417,8 @@ export default {
name: this.editName,
assignment: this.editAssignment
})
.then(week => {
this.week = week
this.closeEditor()
})
.then(this.loadLocalWeek)
.then(this.closeEditor)
.catch(err => {
console.error(err)
})
Expand Down
6 changes: 6 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ export const APPOINTMENTS = ['None', 'Brother', 'Sister', 'Ministerial Servant',
export const GENDERS = ['Male', 'Female']

export const LANGUAGE_GROUPS = ['English', 'Portuguese']

export const WEEK_TYPES = {
normal: { label: 'Normal', value: 0 },
assembly: { label: 'Assembly', value: 1 },
coVisit: { label: 'CO Visit', value: 2 }
}
13 changes: 11 additions & 2 deletions src/plugins/pdfMake.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import pdfMake from 'pdfmake/build/pdfmake'
import pdfFonts from 'pdfmake/build/vfs_fonts'

import store from '@/store'
import { COLORS } from '@/constants'
import { COLORS, WEEK_TYPES } from '@/constants'

pdfMake.vfs = pdfFonts.pdfMake.vfs

Expand Down Expand Up @@ -148,7 +148,7 @@ export function generateSchedule (weeks, month) {

stack.push(createScheduleSeparator(false))
weeks.forEach((week, index) => {
const { date, weeklyBibleReading, songs, assignments } = week
const { type, date, weeklyBibleReading, songs, assignments } = week
const {
openingPrayer,
chairman,
Expand All @@ -172,6 +172,15 @@ export function generateSchedule (weeks, month) {
fontSize: 14,
bold: true
})

// Just add a block of text for assembly weeks
if (type === WEEK_TYPES.assembly.value) {
stack.push({ text: 'No Meeting', fontSize: 32, bold: true, alignment: 'center', margin: [0, 132, 0, 12] })
stack.push({ text: 'Assembly Week', fontSize: 18, alignment: 'center', margin: [0, 0, 0, 132] })
stack.push(createScheduleSeparator())
return
}

stack.push({ text: 'Time Off', bold: true, decoration: 'underline', alignment: 'right' })

// Introduction Section
Expand Down
11 changes: 11 additions & 0 deletions src/store/schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ const actions = {
}
return week
})
},
updateWeekType ({ commit }, { weekID, type }) {
return api.schedule.updateWeekType({ weekID, type })
.then(res => {
const { week, members } = res.data.result
commit('UPDATE_WEEK', week)
for (const member of members) {
commit('congregation/UPDATE_MEMBER', member, { root: true })
}
return week
})
}
}

Expand Down

0 comments on commit 0accbd8

Please sign in to comment.