class RessourceList { /* A wrapper class for the list.js list. * This class is not meant to be used directly, instead it should be used as * a template for concrete ressource list implementations. */ constructor(listElement, options = {}) { if (listElement.dataset.userId) { if (listElement.dataset.userId in nopaque.appClient.users) { this.user = nopaque.appClient.users[listElement.dataset.userId]; } else { console.error(`User not found: ${listElement.dataset.userId}`); return; } } else { this.user = nopaque.appClient.users.self; } this.list = new List(listElement, {...RessourceList.options, ...options}); this.valueNames = ['id']; for (let element of this.list.valueNames) { switch (typeof element) { case 'object': if (element.hasOwnProperty('name')) {this.valueNames.push(element.name);} break; case 'string': this.valueNames.push(element); break; default: console.error(`Unknown value name definition: ${element}`); } } } init(ressources) { this.list.clear(); this.add(Object.values(ressources)); this.list.sort('id', {order: 'desc'}); } patch(patch) { /* * It's not possible to generalize a patch Handler for all type of * ressources. So this method is meant to be an interface. */ console.error('patch method not implemented!'); } add(values) { let ressources = Array.isArray(values) ? values : [values]; // Discard ressource values, that are not defined to be used in the list. ressources = ressources.map(ressource => { let cleanedRessource = {}; for (let [valueName, value] of Object.entries(ressource)) { if (this.valueNames.includes(valueName)) {cleanedRessource[valueName] = value;} } return cleanedRessource; }); // Set a callback function ('() => {return;}') to force List.js perform the // add method asynchronous: https://listjs.com/api/#add this.list.add(ressources, () => {return;}); } remove(id) { this.list.remove('id', id); } replace(id, valueName, newValue) { if (this.valueNames.includes(valueName)) { let item = this.list.get('id', id)[0]; item.values({[valueName]: newValue}); } } } RessourceList.options = {page: 5, pagination: [{innerWindow: 4, outerWindow: 1}]}; class CorpusList extends RessourceList { constructor(listElement, options = {}) { super(listElement, {...CorpusList.options, ...options}); this.user.addEventListener('corporaInit', corpora => this.init(corpora)); this.user.addEventListener('corporaPatch', patch => this.patch(patch)); listElement.addEventListener('click', (event) => {this.onclick(event)}); } onclick(event) { let corpusId = event.target.closest('tr').dataset.id; let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; switch (action) { case 'analyse': window.location.href = nopaque.user.corpora[corpusId].analysis_url; case 'delete': let deleteModalHTML = `