196 lines
8.5 KiB
JavaScript
196 lines
8.5 KiB
JavaScript
const path = require('path')
|
|
const fs = require('fs')
|
|
const {groupTeamsnapItems, parsePositionLabel, compilePositionLabel, teamsnapCallback} = require("../lib/utils")
|
|
const tsUtils = require('../lib/utils')
|
|
const { loadEventLineupEntries } = require('teamsnap.js')
|
|
|
|
exports.partials = path.join(__dirname, "../views/eventlineup/partials")
|
|
exports.helpers = require('../helpers/eventlineup.js')
|
|
|
|
exports.getEventLineup = async (req, res)=>{
|
|
await Promise.all(req.promises)
|
|
const {user, team, members, event, layout, event_lineup, event_lineup_entries, availabilities, availabilitySummary, csrfToken} = req
|
|
attachBenchcoachPropertiesToMember(members, event_lineup_entries, availabilities)
|
|
members.sort(tsUtils.teamsnapMembersSortLineupAvailabilityLastName)
|
|
const scripts = [
|
|
"https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js",
|
|
"/js/eventlineup.js",
|
|
"/js/tinymce.min.js"
|
|
]
|
|
res.render("eventlineup/edit", {user, team, members, event, availabilities, scripts, layout, event_lineup, event_lineup_entries, availabilitySummary, csrfToken})
|
|
}
|
|
|
|
exports.getAdjacentEventLineup = async (req, res) => {
|
|
await Promise.all(req.promises)
|
|
const index = Number(req.query.index)
|
|
const {user, team, members, csrfToken} = req
|
|
let event
|
|
if (index > 0) {
|
|
event = req.upcoming_events[index-1]
|
|
}
|
|
else if (index < 0){
|
|
event = req.recent_events[Math.abs(index)-1]
|
|
} else {
|
|
throw new Error('Index must be positive or negative number')
|
|
}
|
|
if (!event) {
|
|
res.status(500).send()
|
|
return
|
|
}
|
|
const availabilitySummary = event.availabilitySummary
|
|
const event_lineup = req.timeline.event_lineups?.find(i=>i.eventId==event.id)
|
|
const event_lineup_entries = req.timeline.event_lineup_entries?.filter(i=>i.eventId==event.id)
|
|
const availabilities = req.timeline.availabilities.filter(i=>i.eventId==event.id)
|
|
attachBenchcoachPropertiesToMember(members, event_lineup_entries, availabilities)
|
|
members.sort(tsUtils.teamsnapMembersSortLineupAvailabilityLastName)
|
|
console.log()
|
|
|
|
res.render("eventlineup/edit", {user, team, members, event, layout: null, event_lineup, event_lineup_entries, availabilitySummary, availabilities, csrfToken})
|
|
}
|
|
|
|
attachBenchcoachPropertiesToMember = (members, event_lineup_entries, availabilities) => {
|
|
members.forEach((member)=> {
|
|
// I *think* this can be done with linking https://github.com/teamsnap/teamsnap-javascript-sdk/wiki/Persistence#linking
|
|
// here's an example:
|
|
// member.link('eventLineupEntry', event_lineup_entries.find(i=>i.id=members[1].id))
|
|
member.benchcoach = {}
|
|
// I don't really like this, but the member_id changes once a season is archived.
|
|
// as far as I can tell, member_name should consistently be formulated from first and last name
|
|
// perhaps could have some edge cases if first or last names change, but this *should be* exceedingly rare.
|
|
const member_name = `${member.firstName} ${member.lastName}`
|
|
const event_lineup_entry = event_lineup_entries?.find(e=> e.memberId == member.id || e.memberName == member_name)
|
|
const availability = availabilities.find(e=>e.memberId == member.id)
|
|
member.benchcoach.availability = availability
|
|
if (event_lineup_entry != null) {
|
|
// member.link('eventLineupEntry', event_lineup_entry)
|
|
member.benchcoach.eventLineupEntry = event_lineup_entry
|
|
const {positionLabelWithoutFlag, positionFlags} = parsePositionLabel(event_lineup_entry.label);
|
|
member.benchcoach.eventLineupEntry.positionLabelWithoutFlag = positionLabelWithoutFlag
|
|
member.benchcoach.eventLineupEntry.flags = positionFlags
|
|
}
|
|
else {
|
|
member.benchcoach.eventLineupEntry = null
|
|
}
|
|
}
|
|
)
|
|
}
|
|
exports.attachBenchcoachPropertiesToMember = attachBenchcoachPropertiesToMember
|
|
|
|
exports.getEventLineupEmail = async (req, res)=>{
|
|
const {body} = req
|
|
if (body.memberId == null) {res.status(400).end();return}
|
|
await Promise.all(req.promises)
|
|
const {user, team, members, event, layout, event_lineup, event_lineup_entries, availabilities, availabilitySummary} = req
|
|
const eventLineupEntries = req.event_lineup.eventLineupEntries
|
|
const {newEventLineupEntries} = processPostedEventLineupEntries(body, eventLineupEntries, event_lineup)
|
|
attachBenchcoachPropertiesToMember(members, newEventLineupEntries, availabilities)
|
|
members.sort(tsUtils.teamsnapMembersSortLineupAvailabilityLastName)
|
|
res.status(200).render("eventlineup/partials/email_modal.hbs", {layout:null, user, team, members, event, event_lineup, event_lineup_entries: newEventLineupEntries, availabilities, availabilitySummary})
|
|
}
|
|
|
|
exports.getAvailabilityRemindersModal = (req, res) => {
|
|
res.status(200).render("eventlineup/partials/availability_reminder_modal.hbs")
|
|
}
|
|
|
|
exports.getEventLineupEntries = async (req, res)=>{
|
|
const {event_lineup, event_lineup_entries} = req
|
|
res.setHeader('Content-Type', 'application/json').send(JSON.stringify(req.event_lineup_entries))
|
|
}
|
|
|
|
exports.getEventLineupEntriesData = async (req, res)=>{
|
|
const {event_lineup, event_lineup_entries} = req
|
|
res.setHeader('Content-Type', 'application/json').send(JSON.stringify(req.event_lineup_entries))
|
|
}
|
|
|
|
exports.postEventLineup = async (req,res) => {
|
|
const {body} = req
|
|
if (body.memberId == null) {res.status(400).end();return}
|
|
await Promise.all(req.promises);
|
|
const eventLineupEntries = req.event_lineup.eventLineupEntries
|
|
const {newEventLineupEntries, deleteEventLineupEntries} = processPostedEventLineupEntries(body, eventLineupEntries, req.event_lineup)
|
|
newEventLineupEntries.forEach(e=>{
|
|
teamsnap.saveEventLineupEntry(e, teamsnapCallback)
|
|
})
|
|
deleteEventLineupEntries.forEach(e=>{
|
|
teamsnap.deleteEventLineupEntry(e, teamsnapCallback)
|
|
})
|
|
|
|
const bulk_items = await teamsnap.bulkLoad(
|
|
{teamId: req.params.team_id, types: ['eventLineup', 'eventLineupEntry'], scopeTo:'event', event__id:req.params.event_id,},
|
|
null,
|
|
(err, items) => {teamsnapCallback(err, items, {req, source:"postEventLineup", method:'bulkLoad'})}
|
|
)
|
|
groupedReturnedItems = groupTeamsnapItems(bulk_items)
|
|
returnedEventLineupEntries = groupedReturnedItems.eventLineupEntries
|
|
res.status(201).end(JSON.stringify(returnedEventLineupEntries))
|
|
}
|
|
|
|
const processPostedEventLineupEntries = (body, eventLineupEntries, eventLineup) => {
|
|
const newEventLineupEntries = []
|
|
const deleteEventLineupEntries = []
|
|
|
|
body.memberId.forEach((memberId, i)=>{
|
|
const lineupEntryId = body.eventLineupEntryId[i]
|
|
const lineupEntryLabel = body.label[i]
|
|
const lineupEntrySequence = body.sequence[i]
|
|
const lineupEntryFlags = body.flags[i]
|
|
if (lineupEntryId != '' && lineupEntryLabel != '') {
|
|
// Update lineup entry
|
|
try {
|
|
const eventLineupEntry = eventLineupEntries.find((e)=>e.id==Number(lineupEntryId))
|
|
eventLineupEntry.sequence = lineupEntrySequence
|
|
eventLineupEntry.label = compilePositionLabel(lineupEntryLabel, lineupEntryFlags)
|
|
newEventLineupEntries.push(eventLineupEntry)
|
|
} catch {
|
|
console.log
|
|
}
|
|
}
|
|
else if (lineupEntryId != '') {
|
|
// Delete lineup entry
|
|
const eventLineupEntry = eventLineupEntries.find((e)=>e.id==Number(lineupEntryId))
|
|
deleteEventLineupEntries.push(eventLineupEntry)
|
|
}
|
|
else if (lineupEntryLabel != '') {
|
|
// Create lineup entry
|
|
const eventLineupEntry = teamsnap.createEventLineupEntry()
|
|
eventLineupEntry.eventLineupId = eventLineup.id
|
|
eventLineupEntry.memberId = memberId
|
|
eventLineupEntry.sequence = lineupEntrySequence
|
|
eventLineupEntry.label = compilePositionLabel(lineupEntryLabel, lineupEntryFlags)
|
|
newEventLineupEntries.push(eventLineupEntry)
|
|
}
|
|
else {
|
|
// Skip lineup entry
|
|
}
|
|
})
|
|
return {newEventLineupEntries, eventLineupEntries, deleteEventLineupEntries}
|
|
}
|
|
|
|
exports.submitDeleteEventLineupEntries = async (req,res) => {
|
|
await Promise.all(req.promises);
|
|
const {event_lineup, event_lineup_entries} = req
|
|
let event_id
|
|
let memberIds
|
|
|
|
if (!req.body || ! (req.body.event_id && req.body.memberIds)) {
|
|
res.status(400).send('Malformed post')
|
|
} else if (req.params.event_id != req.body.event_id) {
|
|
// Load actual event. Do I want this to be an error? probably
|
|
res.status(400).send('Event ID parameter does not match the POST body');
|
|
return
|
|
} else {
|
|
event_id = req.body.event_id
|
|
memberIds = req.body.memberIds
|
|
}
|
|
|
|
const deletion_promises = []
|
|
|
|
event_lineup_entries.filter(entry =>memberIds.includes(entry.memberId.toString())).forEach( entry => {
|
|
const promise = teamsnap.deleteEventLineupEntry(entry, teamsnapCallback)
|
|
deletion_promises.push(promise)
|
|
})
|
|
|
|
await Promise.all(deletion_promises)
|
|
.then(res.status(202).send('OK'))
|
|
|
|
} |