contacts_events-8.x-1.x-dev/modules/village_allocation/js/village-allocation.js
modules/village_allocation/js/village-allocation.js
var $=jQuery;
var app = new Vue({
el: '#app',
// the VA UI template is defined in village-allocation.ui.js to keep
// this file smaller.
template: villageAllageAllocationUi,
data: {
eventId: null,
groups: [],
totalGroups: 0,
pageNumber: 0,
totalPages: 0,
pageSize: 0,
villages: [],
selectedBookings: [],
showAllocateDialog: false,
showDeallocateDialog: false,
villageToAllocate: null,
csrfToken: null,
error: null,
loading: false,
facets: [],
activeFacets: [],
filters: {
village: 'unallocated',
hasRequirements: 'All',
hideZeroPitches: 1,
searchText: null
}
},
computed: {
bookingsToDeallocate() {
return this.selectedBookings.filter(b => b.village != null);
}
},
methods: {
async allocate() {
let request = {
booking_ids: [],
village_id: this.villageToAllocate.id,
};
// Need to also allocate any child bookings.
for (const booking of this.selectedBookings) {
request.booking_ids.push(booking.id);
for (const childBooking of booking.childBookings) {
request.booking_ids.push(childBooking.id);
}
}
// Fire off the ajax request to do the allocation. Only update
// pitch totals & allocation on the clientside if the request
// is successful.
if (request.booking_ids.length) {
try {
this.loading = true;
await this.post('/admin/village_allocation/allocate/' + this.eventId, request);
for (let booking of this.selectedBookings) {
if (booking.village) {
// If already allocated, decrease the original village's pitches.
this.villages.find(v => v.id == booking.village).pitchesAllocated -= booking.pitches;
}
// Allocate the village and increase pitches allocated.
booking.village = this.villageToAllocate.id;
this.villageToAllocate.pitchesAllocated += booking.pitches;
}
this.showAllocateDialog = false;
this.selectedBookings = [];
// Refresh the bookings list.
await this.loadBookings();
}
catch(error) {
// Cause the error dialog to be shown.
this.error = error.responseText;
}
}
},
async deallocate() {
let request = {
booking_ids: [],
};
// Deallocate the group booking and the child bookings too.
for (const booking of this.selectedBookings) {
request.booking_ids.push(booking.id);
for (const childBooking of booking.childBookings) {
request.booking_ids.push(childBooking.id);
}
}
// Fire off the ajax request to do the deallocation. Only update
// pitch totals & allocation on the clientside if the request
// is successful.
if (request.booking_ids.length) {
try {
this.loading = true;
await this.post('/admin/village_allocation/deallocate/' + this.eventId, request);
for (let booking of this.selectedBookings) {
this.villages.find(v => v.id == booking.village).pitchesAllocated -= booking.pitches;
booking.village = null;
}
this.showDeallocateDialog = false;
this.selectedBookings = [];
// Refresh the booking list.
await this.loadBookings();
}
catch(error) {
// Cause the error dialog to be shown.
this.error = error.responseText;
}
}
},
// Event handler for when bookings have been dropped onto a village.
villageDropped(village) {
this.villageToAllocate = village;
this.allocate();
},
bookingSelected(booking) {
if (!this.selectedBookings.includes(booking)) {
this.selectedBookings.push(booking);
}
},
bookingDeselected(booking) {
let index = this.selectedBookings.indexOf(booking);
if (index > -1) {
this.selectedBookings.splice(index, 1);
}
},
linkedSelected(groupIds) {
for(let group of this.groups) {
if (groupIds.includes(group.id)) {
for(let booking of group.bookings) {
booking.selected = true;
}
}
}
},
linkedDeselected(groupIds) {
for(let group of this.groups) {
if (groupIds.includes(group.id)) {
for(let booking of group.bookings) {
booking.selected = false;
}
}
}
},
// Event handler for when facets are changed, or the search button is clicked.
async facetSearch(filters) {
this.activeFacets = filters;
await this.loadBookings();
},
// Event handler for when the pager changes.
async pagerNavigate(pageNumber) {
this.pageNumber = pageNumber;
await this.loadBookings();
},
clearError() {
this.error = null;
this.loading = false;
},
async loadBookings() {
this.selectedBookings = [];
this.loading = true;
let village = this.filters.village;
let villageOperator = '=';
if (village === 'unallocated') {
// Unallocated translates to "village_id = 0"
village = '0';
}
else if (village === 'any') {
// Any allocated translates to "village_id > 0"
village = '0';
villageOperator = '>';
}
// Note must use "village[value]" not "village" for the solr view to
// pick up the filter correctly.
let data = {
'village[value]': village,
village_op: villageOperator,
has_requirements: this.filters.hasRequirements,
has_pitches: this.filters.hideZeroPitches,
search: this.filters.searchText,
page: this.pageNumber,
f: this.activeFacets,
};
let response = await $.getJSON('/admin/village_allocation/bookings/' + this.eventId, data);
this.groups = response.groups;
this.totalGroups = response.count;
this.pageSize = response.page_size;
this.totalPages = Math.ceil(this.totalGroups / this.pageSize);
this.facets = response.facets;
this.loading = false;
},
async loadVillages() {
this.villages = await $.getJSON('/admin/village_allocation/villages/' + this.eventId);
},
async getCsrfToken() {
this.csrfToken = await $.get(drupalSettings.token_url);
},
post(url, data) {
return $.ajax({
type: 'POST',
data: JSON.stringify(data),
url: url,
dataType: 'json',
contentType: 'application/json',
headers: {
'X-CSRF-Token': this.csrfToken,
},
});
}
},
async mounted() {
this.eventId = drupalSettings.event_id;
// Don't await these - just fire and forget.
this.loadBookings();
this.loadVillages();
this.getCsrfToken();
window.addEventListener('keyup', event => {
// Ensure dialogs are closed when escape key is pressed.
if (event.keyCode === 27) {
app.showAllocateDialog = false;
app.showDeallocateDialog = false;
app.clearError();
}
});
}
});
