Commit 72c218e7 authored by Sandro Lutz's avatar Sandro Lutz
Browse files

Update events model

parent 9d8ea647
import m from 'mithril';
import Stream from 'mithril/stream';
import { apiUrl } from 'config';
import { getToken, getUserId, isLoggedIn } from './auth';
import { currentLanguage } from './language';
const date = `${new Date().toISOString().split('.')[0]}Z`;
let querySaved = '';
/**
* Get the loaded list of events.
*
* @return {array}
* Event class
*/
export function getList() {
if (typeof this.list === 'undefined') {
return [];
export class Event {
constructor(event) {
// Expose all properties of `event`
Object.keys(event).forEach(key => {
this[key] = event[key];
});
}
return this.list;
}
/**
* Get the selected event.
*
* @return {Object} `event` object returned by the AMIV API.
*/
export function getSelectedEvent() {
return this.selectedEvent;
}
/**
* Get signup data for the selected event and the authenticated user.
*
* @return {Object} `eventsignup` object returned by the AMIV API.
*/
export function getSignupForSelectedEvent() {
return this.selectedEventSignup;
}
/**
* Load the signup data of the authenticated user.
* @return {Promise}
*/
async loadSignup() {
if (!isLoggedIn()) return undefined;
/**
* Check if signup data of the authenticated user for the selected event have been loaded.
*
* @return {Boolean}
*/
export function signupForSelectedEventHasLoaded() {
return this.selectedEventSignupLoaded;
}
const queryString = m.buildQueryString({
where: JSON.stringify({
user: getUserId(),
event: this.getSelectedEvent()._id,
}),
});
/**
* Load signup data of the authenticated user for the selected event.
* @return {Promise} exports for additional response handling
*/
export function loadSignupForSelectedEvent() {
const queryString = m.buildQueryString({
where: JSON.stringify({
user: getUserId(),
event: this.getSelectedEvent()._id,
}),
});
return m
.request({
const response = await m.request({
method: 'GET',
url: `${apiUrl}/eventsignups?${queryString}`,
headers: getToken()
? {
Authorization: `Token ${getToken()}`,
}
: {},
})
.then(result => {
[this.selectedEventSignup] = result._items;
this.selectedEventSignupLoaded = true;
headers: {
Authorization: getToken(),
},
});
}
if (response._items.length === 1) {
[this.signup] = response._items;
} else {
this.signup = undefined;
}
this.signupLoaded = true;
return this.signup;
}
export function _signupUserForSelectedEvent(additionalFieldsString) {
if (typeof this.selectedEventSignup !== 'undefined') {
return m
.request({
method: 'PATCH',
url: `${apiUrl}/eventsignups/${this.selectedEventSignup._id}`,
data: {
additional_fields: additionalFieldsString,
},
headers: getToken()
? {
Authorization: `Token ${getToken()}`,
'If-Match': this.selectedEventSignup._etag,
}
: { 'If-Match': this.selectedEventSignup._etag },
})
.then(() => {
this.loadSignupForSelectedEvent();
});
/**
* Checks if the signup data has been loaded.
* @return {Boolean}
*/
hasSignupLoaded() {
return this.signupLoaded;
}
return m
.request({
method: 'POST',
url: `${apiUrl}/eventsignups`,
data: {
event: this.selectedEvent._id,
additional_fields: additionalFieldsString,
user: getUserId(),
/**
* Get signup data of the authenticated user.
*/
getSignup() {
return this.signup;
}
/**
* Sign off the authenticated user from this event.
* @return {Promise}
*/
async signoff() {
if (!this.signup) return;
await m.request({
method: 'DELETE',
url: `${apiUrl}/eventsignups/${this.signup._id}`,
headers: {
Authorization: getToken(),
'If-Match': this.signup._etag,
},
headers: getToken()
? {
Authorization: `Token ${getToken()}`,
}
: {},
})
.then(() => {
this.loadSignupForSelectedEvent();
});
}
this.signup = undefined;
}
export function _signupEmailForSelectedEvent(additionalFieldsString, email) {
return m
.request({
/**
* Sign up the authenticated user for this event.
* @param {*} additionalFields
* @param {string} email email address (required if not logged in!)
* @return {Promise}
*/
async signup(additionalFields, email = '') {
let additionalFieldsString = '';
if (this.selectedEvent.additional_fields) {
additionalFieldsString = JSON.stringify(additionalFields);
}
if (this.signup) {
this._updateSignup(additionalFieldsString);
}
this._createSignup(additionalFieldsString, email);
}
async _createSignup(additionalFieldsString, email = '') {
const data = {
event: this._id,
additional_fields: additionalFieldsString,
};
if (isLoggedIn()) {
data.user = getUserId();
} else if (this.allow_email_signup) {
data.email = email;
} else {
throw new Error('Signup not allowed');
}
this.signup = await m.request({
method: 'POST',
url: `${apiUrl}/eventsignups`,
data,
headers: {
Authorization: getToken(),
},
});
}
async _updateSignup(additionalFieldsString) {
this.signup = await m.request({
method: 'PATCH',
url: `${apiUrl}/eventsignups/${this.signup._id}`,
data: {
event: this.selectedEvent._id,
additional_fields: additionalFieldsString,
email,
},
headers: getToken()
? {
Authorization: `Token ${getToken()}`,
}
: {},
})
.then(() => {
this.loadSignupForSelectedEvent();
headers: {
Authorization: getToken(),
'If-Match': this.signup._etag,
},
});
}
}
/**
* Sign up the authenticated user for the selected event.
*
* @return {Promise} exports for additional response handling
*/
export function signupForSelectedEvent(additionalFields, email = '') {
let additionalFieldsString;
if (
this.selectedEvent.additional_fields === undefined ||
additionalFields === null ||
typeof additionalFields !== 'object'
) {
additionalFieldsString = undefined;
} else {
additionalFieldsString = JSON.stringify(additionalFields);
export class EventController {
constructor(query = {}) {
this.query = query || {};
// state pointer that is counted up every time the table is refreshed so
// we can tell infinite scroll that the data-version has changed.
this.stateCounter = Stream(0);
}
if (isLoggedIn()) {
return this._signupUserForSelectedEvent(additionalFieldsString);
} else if (this.selectedEvent.allow_email_signup) {
return this._signupEmailForSelectedEvent(additionalFieldsString, email);
refresh() {
this.stateCounter(this.stateCounter() + 1);
}
return Promise.reject(new Error('Signup not allowed'));
}
/**
* Sign off the authenticated user from the selected event.
*
* @return {Promise} exports for additional response handling
*/
export function signoffForSelectedEvent() {
if (isLoggedIn() && typeof this.selectedEventSignup !== 'undefined') {
m
.request({
method: 'DELETE',
url: `${apiUrl}/eventsignups/${this.selectedEventSignup._id}`,
headers: getToken()
? {
Authorization: `Token ${getToken()}`,
'If-Match': this.selectedEventSignup._etag,
}
: { 'If-Match': this.selectedEventSignup._etag },
})
.then(() => {
this.loadSignupForSelectedEvent();
});
infiniteScrollParams(item) {
return {
item,
pageData: pageNum => this.getPageData(pageNum),
pageKey: pageNum => `${pageNum}-${this.stateCounter()}`,
};
}
}
/**
* Load events from the AMIV API
*
* @param {*} query filter and sort query for the API request.
* @return {Promise} exports for additional response handling
*/
export function load(query = {}) {
querySaved = query;
// Parse query such that the backend understands it
const parsedQuery = {};
Object.keys(query).forEach(key => {
parsedQuery[key] = key === 'sort' ? query[key] : JSON.stringify(query[key]);
});
const queryString = m.buildQueryString(parsedQuery);
return m
.request({
async getPageData(pageNum) {
// for some reason this is called before the object is instantiated.
// check this and return nothing
const query = Object.assign({}, this.query);
query.max_results = 10;
query.page = pageNum;
// Parse query such that the backend understands it
const parsedQuery = {};
Object.keys(query).forEach(key => {
parsedQuery[key] = key === 'sort' ? query[key] : JSON.stringify(query[key]);
});
const queryString = m.buildQueryString(parsedQuery);
const response = await m.request({
method: 'GET',
url: `${apiUrl}/events?${queryString}`,
headers: getToken()
? {
Authorization: `Token ${getToken()}`,
}
: {},
})
.then(result => {
this.list = result._items.map(event => {
const newEvent = Object.assign({}, event);
newEvent.title = newEvent[`title_${currentLanguage()}`];
newEvent.description = newEvent[`description_${currentLanguage()}`];
return newEvent;
});
headers: {
Authorization: getToken(),
},
});
}
return response._items.map(event => {
const newEvent = Object.assign({}, event);
newEvent.title = newEvent[`title_${currentLanguage()}`];
newEvent.description = newEvent[`description_${currentLanguage()}`];
return Event(newEvent);
});
}
/**
* Select an event from the event list.
*
* @param {String} eventId event id from AMIV API
*/
export function selectEvent(eventId) {
this.selectedEvent = this.getList().find(item => item._id === eventId);
if (typeof this.selectedEvent === 'undefined') {
this.load({
where: {
time_advertising_start: { $lte: date },
time_advertising_end: { $gte: date },
show_website: true,
setQuery(query) {
this.query = query;
this.refresh();
}
/**
* Load a specific event
* @param {String} eventId
*/
static async loadEvent(eventId) {
const event = await m.request({
method: 'GET',
url: `${apiUrl}/events/${eventId}`,
headers: {
Authorization: getToken(),
},
sort: ['-priority', 'time_advertising_start'],
}).then(() => {
this.selectedEvent = this.getList().find(item => item._id === eventId);
});
event.title = event[`title_${currentLanguage()}`];
event.description = event[`description_${currentLanguage()}`];
return Event(event);
}
}
/**
* Reload event list with the same query as before.
*
* @return {Promise} exports for additional response handling
*/
export function reload() {
return load(querySaved);
}
......@@ -57,7 +57,40 @@ export default class EventList {
},
}),
]),
m(
// filtered content view
m('div.content', [
m('div.content-grid', [
tableHeadings.map(header => m('div.list-header', header)),
studydocs
.getList()
.map(doc => [
m('div.list-item', { onclick: () => this.selectDocument(doc) }, doc.title),
m('div.list-item', { onclick: () => this.selectDocument(doc) }, doc.type),
]),
]),
]),
// detail view of selected studydoc item
this.doc
? m('div.details', [
m('table', [
m('tr', this.doc.title),
m('tr', this.doc.lecture),
m('tr', this.doc.professor),
m('tr', this.doc.semester),
m('tr', this.doc.author),
m(Button, {
label: 'Download',
events: {
onclick: () => window.open(`${apiUrl}${this.doc.files[0].file}`, '_blank'),
},
}),
]),
])
: m(''),
]);
/* m(
'tbody',
events
.getList()
......@@ -78,6 +111,6 @@ export default class EventList {
])
)
),
]);
]); */
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment