diff --git a/web/app/static/js/nopaque.js b/web/app/static/js/nopaque.js deleted file mode 100644 index bd5e3f4e..00000000 --- a/web/app/static/js/nopaque.js +++ /dev/null @@ -1,207 +0,0 @@ -class AppClient { - constructor(currentUserId) { - this.socket = io({transports: ['websocket']}); - this.users = {}; - this.users.self = this.loadUser(currentUserId); - } - - loadUser(userId) { - let user = new User(); - this.users[userId] = user; - this.socket.on(`user_${userId}_init`, msg => user.init(JSON.parse(msg))); - this.socket.on(`user_${userId}_patch`, msg => user.patch(JSON.parse(msg))); - this.socket.emit('start_user_session', userId); - return user; - } -} - - -class User { - constructor() { - this.data = undefined; - this.eventListeners = { - corporaInit: [], - corporaPatch: [], - jobsInit: [], - jobsPatch: [], - queryResultsInit: [], - queryResultsPatch: [] - }; - } - - init(data) { - this.data = data; - - let listener; - for (listener of this.eventListeners.corporaInit) { - listener(this.data.corpora); - } - for (listener of this.eventListeners.jobsInit) { - listener(this.data.jobs); - } - for (listener of this.eventListeners.queryResultsInit) { - listener(this.data.query_results); - } - } - - patch(patch) { - this.data = jsonpatch.apply_patch(this.data, patch); - - let corporaPatch = patch.filter(operation => operation.path.startsWith("/corpora")); - let jobsPatch = patch.filter(operation => operation.path.startsWith("/jobs")); - let queryResultsPatch = patch.filter(operation => operation.path.startsWith("/query_results")); - - for (let listener of this.eventListeners.corporaPatch) { - if (corporaPatch.length > 0) {listener(corporaPatch);} - } - for (let listener of this.eventListeners.jobsPatch) { - if (jobsPatch.length > 0) {listener(jobsPatch);} - } - for (let listener of this.eventListeners.queryResultsPatch) { - if (queryResultsPatch.length > 0) {listener(queryResultsPatch);} - } - - for (let operation of jobsPatch) { - if (operation.op !== 'replace') {continue;} - // Matches the only path that should be handled here: /jobs/{jobId}/status - if (/^\/jobs\/(\d+)\/status$/.test(operation.path)) { - let [match, jobId] = operation.path.match(/^\/jobs\/(\d+)\/status$/); - if (this.data.settings.job_status_site_notifications === "end" && !["complete", "failed"].includes(operation.value)) {continue;} - nopaque.flash(`[${this.data.jobs[jobId].title}] New status: ${operation.value}`, "job"); - } - } - } - - addEventListener(type, listener) { - switch (type) { - case 'corporaInit': - this.eventListeners.corporaInit.push(listener); - if (this.data !== undefined) {listener(this.data.corpora);} - break; - case 'corporaPatch': - this.eventListeners.corporaPatch.push(listener); - break; - case 'jobsInit': - this.eventListeners.jobsInit.push(listener); - if (this.data !== undefined) {listener(this.data.jobs);} - break; - case 'jobsPatch': - this.eventListeners.jobsPatch.push(listener); - break; - case 'queryResultsInit': - this.eventListeners.queryResultsInit.push(listener); - if (this.data !== undefined) {listener(this.data.query_results);} - break; - case 'queryResultsPatch': - this.eventListeners.queryResultsPatch.push(listener); - break; - default: - console.error(`Unknown event type: ${type}`); - } - } -} - - -/* - * The nopaque object is used as a namespace for nopaque specific functions and - * variables. - */ -var nopaque = {}; - -nopaque.flash = function(message, category) { - let toast; - let toastActionElement; - - switch (category) { - case "corpus": - message = `book${message}`; - break; - case "error": - message = `error${message}`; - break; - case "job": - message = `work${message}`; - break; - default: - message = `notifications${message}`; - } - - toast = M.toast({html: `${message} - `}); - toastActionElement = toast.el.querySelector('.toast-action[data-action="close"]'); - toastActionElement.addEventListener('click', () => {toast.dismiss();}); -}; - -nopaque.Forms = {}; -nopaque.Forms.init = function() { - var abortRequestElement, parentElement, progressElement, progressModal, - progressModalElement, request, submitElement; - - for (let form of document.querySelectorAll(".nopaque-submit-form")) { - submitElement = form.querySelector('button[type="submit"]'); - submitElement.addEventListener("click", function() { - for (let selectElement of form.querySelectorAll('select')) { - if (selectElement.value === "") { - parentElement = selectElement.closest(".input-field"); - parentElement.querySelector(".select-dropdown").classList.add("invalid"); - for (let helperTextElement of parentElement.querySelectorAll(".helper-text")) { - helperTextElement.remove(); - } - parentElement.insertAdjacentHTML("beforeend", `Please select an option.`); - } - } - }); - - request = new XMLHttpRequest(); - if (form.dataset.hasOwnProperty("progressModal")) { - progressModalElement = document.getElementById(form.dataset.progressModal); - progressModal = M.Modal.getInstance(progressModalElement); - progressModal.options.dismissible = false; - abortRequestElement = progressModalElement.querySelector(".abort-request"); - abortRequestElement.addEventListener("click", function() {request.abort();}); - progressElement = progressModalElement.querySelector(".determinate"); - } - form.addEventListener("submit", function(event) { - event.preventDefault(); - var formData; - - formData = new FormData(form); - // Initialize progress modal - if (progressModalElement) { - progressElement.style.width = "0%"; - progressModal.open(); - } - request.open("POST", window.location.href); - request.send(formData); - }); - request.addEventListener("load", function(event) { - var fieldElement; - - if (request.status === 201) { - window.location.href = JSON.parse(this.responseText).redirect_url; - } - if (request.status === 400) { - console.log(request); - for (let [field, errors] of Object.entries(JSON.parse(this.responseText))) { - fieldElement = form.querySelector(`input[name$="${field}"]`).closest(".input-field"); - for (let error of errors) { - fieldElement.insertAdjacentHTML("beforeend", `${error}`); - } - } - if (progressModalElement) { - progressModal.close(); - } - } - if (request.status === 500) { - location.reload(); - } - }); - if (progressModalElement) { - request.upload.addEventListener("progress", function(event) { - progressElement.style.width = Math.floor(100 * event.loaded / event.total).toString() + "%"; - }); - } - } -} diff --git a/web/app/static/js/nopaque.lists.js b/web/app/static/js/nopaque.lists.js deleted file mode 100644 index 36ea8b48..00000000 --- a/web/app/static/js/nopaque.lists.js +++ /dev/null @@ -1,258 +0,0 @@ -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 = ``; - let deleteModalParentElement = document.querySelector('main'); - deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML); - let deleteModalElement = deleteModalParentElement.lastChild; - let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}}); - deleteModal.open(); - break; - case 'view': - // TODO: handle unprepared corpora - window.location.href = nopaque.user.corpora[corpusId].url; - break; - default: - console.error(`Unknown action: ${action}`); - break; - } - } - - patch(patch) { - for (let operation of patch) { - switch(operation.op) { - case 'add': - // Matches the only paths that should be handled here: /corpora/{corpusId} - if (/^\/corpora\/(\d+)$/.test(operation.path)) {this.add(operation.value);} - break; - case 'remove': - // See case 'add' ;) - if (/^\/corpora\/(\d+)$/.test(operation.path)) { - let [match, id] = operation.path.match(/^\/corpora\/(\d+)$/); - this.remove(corpusId); - } - break; - case 'replace': - // Matches the only paths that should be handled here: /corpora/{corpusId}/{status || description || title} - if (/^\/corpora\/(\d+)\/(status|description|title)$/.test(operation.path)) { - let [match, id, valueName] = operation.path.match(/^\/corpora\/(\d+)\/(status|description|title)$/); - this.replace(id, valueName, operation.value); - } - break; - default: - break; - } - } - } -} -CorpusList.options = { - item: ` - book -
- - - delete - search - send - - `, - valueNames: [{data: ['id']}, {name: 'status', attr: 'data-status'}, 'description', 'title'] -}; - - -class JobList extends RessourceList { - constructor(listElement, options = {}) { - super(listElement, {...JobList.options, ...options}); - this.user.addEventListener('jobsInit', jobs => this.init(jobs)); - this.user.addEventListener('jobsPatch', patch => this.patch(patch)); - listElement.addEventListener('click', (event) => {this.onclick(event)}); - } - - onclick(event) { - let jobId = event.target.closest('tr').dataset.id; - let actionButtonElement = event.target.closest('.action-button'); - let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; - switch (action) { - case 'delete': - let deleteModalHTML = ``; - let deleteModalParentElement = document.querySelector('main'); - deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML); - let deleteModalElement = deleteModalParentElement.lastChild; - let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}}); - deleteModal.open(); - break; - case 'view': - window.location.href = this.user.data.jobs[jobId].url; - break; - default: - console.error(`Unknown action: "${action}"`); - break; - } - } - - patch(patch) { - for (let operation of patch) { - switch(operation.op) { - case 'add': - // Matches the only paths that should be handled here: /jobs/{jobId} - if (/^\/jobs\/(\d+)$/.test(operation.path)) {this.add(operation.value);} - break; - case 'remove': - // See case add ;) - if (/^\/jobs\/(\d+)$/.test(operation.path)) { - let [match, id] = operation.path.match(/^\/jobs\/(\d+)$/); - this.remove(jobId); - } - break; - case 'replace': - // Matches the only paths that should be handled here: /jobs/{jobId}/{service || status || description || title} - if (/^\/jobs\/(\d+)\/(service|status|description|title)$/.test(operation.path)) { - let [match, id, valueName] = operation.path.match(/^\/jobs\/(\d+)\/(service|status|description|title)$/); - this.replace(id, valueName, operation.value); - } - break; - default: - break; - } - } - } -} -JobList.options = { - item: ` - -
- - - delete - send - - `, - valueNames: [{data: ['id']}, {name: 'service', attr: 'data-service'}, {name: 'status', attr: 'data-status'}, 'description', 'title'] -}; - - -class QueryResultList extends RessourceList { - constructor(listElement, options = {}) { - super(listElement, {...QueryResultList.options, ...options}); - this.user.addEventListener('queryResultsInit', queryResults => this.init(queryResults)); - this.user.addEventListener('queryResultsPatch', patch => this.init(patch)); - } -} -QueryResultList.options = { - item: ` -

-
- - delete - send - search - - `, - valueNames: [{data: ['id']}, 'corpus_title', 'description', 'query', 'title'] -}; diff --git a/web/app/static/js/nopaque.lists.js.bak b/web/app/static/js/nopaque.lists.js.bak deleted file mode 100644 index c907f5be..00000000 --- a/web/app/static/js/nopaque.lists.js.bak +++ /dev/null @@ -1,420 +0,0 @@ -class RessourceList extends List { - constructor(idOrElement, subscriberList, type, options) { - if (!type || !["Corpus", "CorpusFile", "Job", "JobInput", "QueryResult", "User"].includes(type)) { - throw "Unknown Type!"; - } - super(idOrElement, {...RessourceList.options['common'], - ...RessourceList.options[type], - ...(options ? options : {})}); - if (subscriberList) {subscriberList.push(this);} - this.type = type; - } - - - _init(ressources) { - this.clear(); - this._add(Object.values(ressources)); - this.sort("id", {order: "desc"}); - } - - - _update(patch) { - let item, pathArray; - - for (let operation of patch) { - /* "/{ressourceName}/{ressourceId}/..." -> ["{ressourceId}", "..."] */ - pathArray = operation.path.split("/").slice(2); - switch(operation.op) { - case "add": - if (pathArray.includes("results")) {break;} - this._add([operation.value]); - break; - case "remove": - this.remove("id", pathArray[0]); - break; - case "replace": - item = this.get("id", pathArray[0])[0]; - switch(pathArray[1]) { - case "status": - item.values({status: operation.value, - "analyse-link": ["analysing", "prepared", "start analysis"].includes(operation.value) ? `/corpora/${pathArray[0]}/analyse` : ""}); - break; - default: - break; - } - default: - break; - } - } - } - - _add(values, callback) { - this.add(values.map(x => RessourceList.dataMappers[this.type](x)), callback); - // Initialize modal and tooltipped elements in list - M.AutoInit(this.listContainer); - } -} - - - - -RessourceList.dataMappers = { - // A data mapper describes entitys rendered per row. One key value pair holds - // the data to be rendered in the list.js table. Key has to correspond - // with the ValueNames defined below in RessourceList.options ValueNames. - // Links are declared with double ticks(") around them. The key for links - // have to correspond with the class of an element in the - // RessourceList.options item blueprint. - - /* ### Corpus mapper ### */ - Corpus: corpus => ({ - creation_date: corpus.creation_date, - description: corpus.description, - id: corpus.id, - link: `/corpora/${corpus.id}`, - status: corpus.status, - title: corpus.title, - title1: corpus.title, - "analyse-link": ["analysing", "prepared", "start analysis"].includes(corpus.status) ? `/corpora/${corpus.id}/analyse` : "", - "delete-link": `/corpora/${corpus.id}/delete`, - "delete-modal": `delete-corpus-${corpus.id}-modal`, - "delete-modal-trigger": `delete-corpus-${corpus.id}-modal`, - }), - /* ### CorpusFile mapper ### TODO: replace delete-modal with delete-onclick */ - CorpusFile: corpus_file => ({ - author: corpus_file.author, - filename: corpus_file.filename, - id: corpus_file.id, - link: `${corpus_file.corpus_id}/files/${corpus_file.id}`, - "publishing-year": corpus_file.publishing_year, - title: corpus_file.title, - title1: corpus_file.title, - "delete-link": `/corpora/${corpus_file.corpus_id}/files/${corpus_file.id}/delete`, - "delete-modal": `delete-corpus-file-${corpus_file.id}-modal`, - "delete-modal-trigger": `delete-corpus-file-${corpus_file.id}-modal`, - "download-link": `${corpus_file.corpus_id}/files/${corpus_file.id}/download`, - }), - /* ### Job mapper ### */ - Job: job => ({ - creation_date: job.creation_date, - description: job.description, - id: job.id, - link: `/jobs/${job.id}`, - service: job.service.name, - status: job.status, - title: job.title, - title1: job.title, - "delete-link": `/jobs/${job.id}/delete`, - "delete-modal": `delete-job-${job.id}-modal`, - "delete-modal-trigger": `delete-job-${job.id}-modal`, - }), - /* ### JobInput mapper ### */ - JobInput: job_input => ({ - filename: job_input.filename, - id: job_input.job_id, - "download-link": `${job_input.job_id}/inputs/${job_input.id}/download` - }), - /* ### QueryResult mapper ### */ - QueryResult: query_result => ({ - corpus_name: query_result.query_metadata.corpus_name, - description: query_result.description, - id: query_result.id, - link: `/corpora/result/${query_result.id}`, - query: query_result.query_metadata.query, - title: query_result.title, - "delete-link": `/corpora/result/${query_result.id}/delete`, - "delete-modal": `delete-query-result-${query_result.id}-modal`, - "delete-modal-trigger": `delete-query-result-${query_result.id}-modal`, - "inspect-link": `/corpora/result/${query_result.id}/inspect`, - }), - /* ### User mapper ### */ - User: user => ({ - confirmed: user.confirmed, - email: user.email, - id: user.id, - link: `users/${user.id}`, - role: user.role.name, - username: user.username, - username2: user.username, - "delete-link": `/admin/users/${user.id}/delete`, - "delete-modal": `delete-user-${user.id}-modal`, - "delete-modal-trigger": `delete-user-${user.id}-modal`, - }), -}; - - -RessourceList.options = { - // common list.js options for 5 rows per page etc. - common: {page: 5, pagination: [{innerWindow: 4, outerWindow: 1}]}, - // extended list.js options for 10 rows per page etc. - extended: { - page: 10, - pagination: [ - { - name: "paginationTop", - paginationClass: "paginationTop", - innerWindow: 8, - outerWindow: 1 - }, - { - paginationClass: "paginationBottom", - innerWindow: 8, - outerWindow: 1, - }, - ], - }, - /* Type specific List.js options. Usually only "item" and "valueNames" gets - * defined here but it is possible to define other List.js options. - * item: https://listjs.com/api/#item - * valueNames: https://listjs.com/api/#valueNames - */ - Corpus: { - item: ` - - - book - - - -
- - - - - - -
- - delete - - - edit - - - search - -
- - - `, - valueNames: [ - "creation_date", - "description", - "title", - "title1", - {data: ["id"]}, - {name: "analyse-link", attr: "href"}, - {name: "delete-link", attr: "href"}, - {name: "delete-modal-trigger", attr: "data-target"}, - {name: "delete-modal", attr: "id"}, - {name: "link", attr: "href"}, - {name: "status", attr: "data-status"}, - ] - }, - CorpusFile: { - item: ` - - - - - -
- - delete - - - file_download - - - edit - -
- - - `, - valueNames: [ - "author", - "filename", - "publishing-year", - "title", - "title1", - {data: ["id"]}, - {name: "delete-link", attr: "href"}, - {name: "delete-modal-trigger", attr: "data-target"}, - {name: "delete-modal", attr: "id"}, - {name: "download-link", attr: "href"}, - {name: "link", attr: "href"}, - ], - }, - Job: { - item: ` - - - - - - -
- - - - - - -
- - delete - - - send - -
- - - `, - valueNames: [ - "creation_date", - "description", - "title", - "title1", - {data: ["id"]}, - {name: "delete-link", attr: "href"}, - {name: "delete-modal-trigger", attr: "data-target"}, - {name: "delete-modal", attr: "id"}, - {name: "link", attr: "href"}, - {name: "service", attr: "data-service"}, - {name: "status", attr: "data-status"}, - ], - }, - JobInput: { - item : ` - - - - file_download - - - `, - valueNames: [ - "filename", - "id", - {name: "download-link", attr: "href"}, - ], - }, - QueryResult: { - item: ` - -
-
- - -
- - - -
- - delete - - - info - - - search - -
- - - `, - valueNames: [ - "corpus_name", - "description", - "query", - "title", - "title2", - {data: ["id"]}, - {name: "delete-link", attr: "href"}, - {name: "delete-modal-trigger", attr: "data-target"}, - {name: "delete-modal", attr: "id"}, - {name: "inspect-link", attr: "href"}, - {name: "link", attr: "href"}, - ], - }, - User: { - item: ` - - - - - -
- - delete - - - send - -
- - - `, - valueNames: [ - "username", - "username2", - "email", - "role", - "id", - {name: "link", attr: "href"}, - {name: "delete-link", attr: "href"}, - {name: "delete-modal-trigger", attr: "data-target"}, - {name: "delete-modal", attr: "id"}, - ], - }, -}; - -export { RessourceList, }; diff --git a/web/app/static/js/nopaque/displays/CorpusDisplay.js b/web/app/static/js/nopaque/RessourceDisplays/CorpusDisplay.js similarity index 100% rename from web/app/static/js/nopaque/displays/CorpusDisplay.js rename to web/app/static/js/nopaque/RessourceDisplays/CorpusDisplay.js diff --git a/web/app/static/js/nopaque/displays/JobDisplay.js b/web/app/static/js/nopaque/RessourceDisplays/JobDisplay.js similarity index 100% rename from web/app/static/js/nopaque/displays/JobDisplay.js rename to web/app/static/js/nopaque/RessourceDisplays/JobDisplay.js diff --git a/web/app/static/js/nopaque/displays/RessourceDisplay.js b/web/app/static/js/nopaque/RessourceDisplays/RessourceDisplay.js similarity index 100% rename from web/app/static/js/nopaque/displays/RessourceDisplay.js rename to web/app/static/js/nopaque/RessourceDisplays/RessourceDisplay.js diff --git a/web/app/static/js/nopaque/lists/CorpusFileList.js b/web/app/static/js/nopaque/RessourceLists/CorpusFileList.js similarity index 100% rename from web/app/static/js/nopaque/lists/CorpusFileList.js rename to web/app/static/js/nopaque/RessourceLists/CorpusFileList.js diff --git a/web/app/static/js/nopaque/lists/CorpusList.js b/web/app/static/js/nopaque/RessourceLists/CorpusList.js similarity index 98% rename from web/app/static/js/nopaque/lists/CorpusList.js rename to web/app/static/js/nopaque/RessourceLists/CorpusList.js index 13197534..c7561615 100644 --- a/web/app/static/js/nopaque/lists/CorpusList.js +++ b/web/app/static/js/nopaque/RessourceLists/CorpusList.js @@ -6,6 +6,7 @@ class CorpusList extends RessourceList { } init(corpora) { + console.log('CorpusList.init called'); this.corpora = corpora; super.init(corpora); } diff --git a/web/app/static/js/nopaque/lists/JobInputList.js b/web/app/static/js/nopaque/RessourceLists/JobInputList.js similarity index 100% rename from web/app/static/js/nopaque/lists/JobInputList.js rename to web/app/static/js/nopaque/RessourceLists/JobInputList.js diff --git a/web/app/static/js/nopaque/lists/JobList.js b/web/app/static/js/nopaque/RessourceLists/JobList.js similarity index 100% rename from web/app/static/js/nopaque/lists/JobList.js rename to web/app/static/js/nopaque/RessourceLists/JobList.js diff --git a/web/app/static/js/nopaque/lists/JobResultList.js b/web/app/static/js/nopaque/RessourceLists/JobResultList.js similarity index 100% rename from web/app/static/js/nopaque/lists/JobResultList.js rename to web/app/static/js/nopaque/RessourceLists/JobResultList.js diff --git a/web/app/static/js/nopaque/lists/QueryResultList.js b/web/app/static/js/nopaque/RessourceLists/QueryResultList.js similarity index 100% rename from web/app/static/js/nopaque/lists/QueryResultList.js rename to web/app/static/js/nopaque/RessourceLists/QueryResultList.js diff --git a/web/app/static/js/nopaque/lists/RessourceList.js b/web/app/static/js/nopaque/RessourceLists/RessourceList.js similarity index 100% rename from web/app/static/js/nopaque/lists/RessourceList.js rename to web/app/static/js/nopaque/RessourceLists/RessourceList.js diff --git a/web/app/static/js/nopaque/lists/Userlist.js b/web/app/static/js/nopaque/RessourceLists/Userlist.js similarity index 100% rename from web/app/static/js/nopaque/lists/Userlist.js rename to web/app/static/js/nopaque/RessourceLists/Userlist.js diff --git a/web/app/static/js/nopaque/main.js b/web/app/static/js/nopaque/main.js index c8f886be..3adafaff 100644 --- a/web/app/static/js/nopaque/main.js +++ b/web/app/static/js/nopaque/main.js @@ -24,6 +24,18 @@ class User { corpus: { addEventListener(listener, corpusId='*') { if (corpusId in this) {this[corpusId].push(listener);} else {this[corpusId] = [listener];} + if (this.data !== undefined) { + console.log('User data is already initialized'); + if (corpusId === '*') { + console.log('*'); + listener(this.data.corpora); + } else if (corpusId in this.data.corpora) { + console.log(corpusId); + listener(this.data.corpora[corpusId]); + } + } else { + console.log('User data is not initialized'); + } } }, job: { @@ -40,6 +52,7 @@ class User { } init(data) { + console.log('User.init called'); this.data = data; for (let [corpusId, eventListeners] of Object.entries(this.eventListeners.corpus)) { diff --git a/web/app/templates/nopaque.html.j2 b/web/app/templates/nopaque.html.j2 index c5085490..3e7978bc 100644 --- a/web/app/templates/nopaque.html.j2 +++ b/web/app/templates/nopaque.html.j2 @@ -254,17 +254,17 @@ - - - - - - - - - - - + + + + + + + + + + + -