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

Update events model

parent 9d8ea647
...@@ -24,10 +24,11 @@ ...@@ -24,10 +24,11 @@
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"email-validator": "^2.0.3", "email-validator": "^2.0.3",
"i18n4v": "^0.2.2", "i18n4v": "^0.2.2",
"marked": "^0.3.18",
"mithril": "^1.1.5", "mithril": "^1.1.5",
"mithril-infinite": "^1.2.4",
"polythene-css": "^1.0.0", "polythene-css": "^1.0.0",
"polythene-mithril": "^1.0.0", "polythene-mithril": "^1.0.0",
"marked": "^0.3.18",
"raven-js": "^3.24.2" "raven-js": "^3.24.2"
}, },
"devDependencies": { "devDependencies": {
......
import m from 'mithril'; import m from 'mithril';
import Stream from 'mithril/stream';
import { apiUrl } from 'config'; import { apiUrl } from 'config';
import { getToken, getUserId, isLoggedIn } from './auth'; import { getToken, getUserId, isLoggedIn } from './auth';
import { currentLanguage } from './language'; import { currentLanguage } from './language';
const date = `${new Date().toISOString().split('.')[0]}Z`;
let querySaved = '';
/** /**
* Get the loaded list of events. * Event class
*
* @return {array}
*/ */
export function getList() { export class Event {
if (typeof this.list === 'undefined') { constructor(event) {
return []; // 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. * Load the signup data of the authenticated user.
* * @return {Promise}
* @return {Object} `eventsignup` object returned by the AMIV API. */
*/ async loadSignup() {
export function getSignupForSelectedEvent() { if (!isLoggedIn()) return undefined;
return this.selectedEventSignup;
}
/** const queryString = m.buildQueryString({
* Check if signup data of the authenticated user for the selected event have been loaded. where: JSON.stringify({
* user: getUserId(),
* @return {Boolean} event: this.getSelectedEvent()._id,
*/ }),
export function signupForSelectedEventHasLoaded() { });
return this.selectedEventSignupLoaded;
}
/** const response = await m.request({
* 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({
method: 'GET', method: 'GET',
url: `${apiUrl}/eventsignups?${queryString}`, url: `${apiUrl}/eventsignups?${queryString}`,
headers: getToken() headers: {
? { Authorization: getToken(),
Authorization: `Token ${getToken()}`, },
}
: {},
})
.then(result => {
[this.selectedEventSignup] = result._items;
this.selectedEventSignupLoaded = true;
}); });
} 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') { * Checks if the signup data has been loaded.
return m * @return {Boolean}
.request({ */
method: 'PATCH', hasSignupLoaded() {
url: `${apiUrl}/eventsignups/${this.selectedEventSignup._id}`, return this.signupLoaded;
data: {
additional_fields: additionalFieldsString,
},
headers: getToken()
? {
Authorization: `Token ${getToken()}`,
'If-Match': this.selectedEventSignup._etag,
}
: { 'If-Match': this.selectedEventSignup._etag },
})
.then(() => {
this.loadSignupForSelectedEvent();
});
} }
return m /**
.request({ * Get signup data of the authenticated user.
method: 'POST', */
url: `${apiUrl}/eventsignups`, getSignup() {
data: { return this.signup;
event: this.selectedEvent._id, }
additional_fields: additionalFieldsString,
user: getUserId(), /**
* 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 * Sign up the authenticated user for this event.
.request({ * @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', method: 'POST',
url: `${apiUrl}/eventsignups`, url: `${apiUrl}/eventsignups`,
data,
headers: {
Authorization: getToken(),
},
});
}
async _updateSignup(additionalFieldsString) {
this.signup = await m.request({
method: 'PATCH',
url: `${apiUrl}/eventsignups/${this.signup._id}`,
data: { data: {
event: this.selectedEvent._id,
additional_fields: additionalFieldsString, additional_fields: additionalFieldsString,
email,
}, },
headers: getToken() headers: {
? { Authorization: getToken(),
Authorization: `Token ${getToken()}`, 'If-Match': this.signup._etag,
} },
: {},
})
.then(() => {
this.loadSignupForSelectedEvent();
}); });
}
} }
/** export class EventController {
* Sign up the authenticated user for the selected event. constructor(query = {}) {
* this.query = query || {};
* @return {Promise} exports for additional response handling // state pointer that is counted up every time the table is refreshed so
*/ // we can tell infinite scroll that the data-version has changed.
export function signupForSelectedEvent(additionalFields, email = '') { this.stateCounter = Stream(0);
let additionalFieldsString;
if (
this.selectedEvent.additional_fields === undefined ||
additionalFields === null ||
typeof additionalFields !== 'object'
) {
additionalFieldsString = undefined;
} else {
additionalFieldsString = JSON.stringify(additionalFields);
} }
if (isLoggedIn()) { refresh() {
return this._signupUserForSelectedEvent(additionalFieldsString); this.stateCounter(this.stateCounter() + 1);
} else if (this.selectedEvent.allow_email_signup) {
return this._signupEmailForSelectedEvent(additionalFieldsString, email);
} }
return Promise.reject(new Error('Signup not allowed'));
}
/** infiniteScrollParams(item) {
* Sign off the authenticated user from the selected event. return {
* item,
* @return {Promise} exports for additional response handling pageData: pageNum => this.getPageData(pageNum),
*/ pageKey: pageNum => `${pageNum}-${this.stateCounter()}`,
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();
});
} }
}
/** async getPageData(pageNum) {
* Load events from the AMIV API // for some reason this is called before the object is instantiated.
* // check this and return nothing
* @param {*} query filter and sort query for the API request. const query = Object.assign({}, this.query);
* @return {Promise} exports for additional response handling query.max_results = 10;
*/ query.page = pageNum;
export function load(query = {}) {
querySaved = query; // Parse query such that the backend understands it
const parsedQuery = {};
// Parse query such that the backend understands it Object.keys(query).forEach(key => {
const parsedQuery = {}; parsedQuery[key] = key === 'sort' ? query[key] : JSON.stringify(query[key]);
Object.keys(query).forEach(key => { });
parsedQuery[key] = key === 'sort' ? query[key] : JSON.stringify(query[key]); const queryString = m.buildQueryString(parsedQuery);
});
const queryString = m.buildQueryString(parsedQuery); const response = await m.request({
return m
.request({
method: 'GET', method: 'GET',
url: `${apiUrl}/events?${queryString}`, url: `${apiUrl}/events?${queryString}`,
headers: getToken() headers: {
? { Authorization: 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;
});
}); });
} return response._items.map(event => {
const newEvent = Object.assign({}, event);
newEvent.title = newEvent[`title_${currentLanguage()}`];
newEvent.description = newEvent[`description_${currentLanguage()}`];
return Event(newEvent);
});
}
/** setQuery(query) {
* Select an event from the event list. this.query = query;
* this.refresh();
* @param {String} eventId event id from AMIV API }
*/
export function selectEvent(eventId) { /**
this.selectedEvent = this.getList().find(item => item._id === eventId); * Load a specific event
if (typeof this.selectedEvent === 'undefined') { * @param {String} eventId
this.load({ */
where: { static async loadEvent(eventId) {
time_advertising_start: { $lte: date }, const event = await m.request({
time_advertising_end: { $gte: date }, method: 'GET',
show_website: true, 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 { ...@@ -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', 'tbody',
events events
.getList() .getList()
...@@ -78,6 +111,6 @@ export default class EventList { ...@@ -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