From 12ec6be60bb18e6366117d27c49b21341055c4ec Mon Sep 17 00:00:00 2001 From: Patrick Jentsch <p.jentsch@uni-bielefeld.de> Date: Wed, 1 Dec 2021 14:15:20 +0100 Subject: [PATCH] JS codestyle enhancements --- app/static/js/nopaque/App.js | 60 ++++++++---- app/static/js/nopaque/JobStatusNotifier.js | 6 +- .../RessourceDisplays/CorpusDisplay.js | 90 ++++++++++-------- .../nopaque/RessourceDisplays/JobDisplay.js | 55 +++++++---- .../RessourceDisplays/RessourceDisplay.js | 10 +- .../nopaque/RessourceLists/CorpusFileList.js | 52 +++++++--- .../js/nopaque/RessourceLists/CorpusList.js | 52 +++++++--- .../js/nopaque/RessourceLists/JobInputList.js | 13 ++- .../js/nopaque/RessourceLists/JobList.js | 56 +++++++---- .../nopaque/RessourceLists/JobResultList.js | 28 ++++-- .../nopaque/RessourceLists/QueryResultList.js | 54 ++++++++--- .../js/nopaque/RessourceLists/UserList.js | 35 +++++-- app/templates/admin/edit_user.html.j2 | 2 +- app/templates/admin/user.html.j2 | 7 +- app/templates/admin/users.html.j2 | 2 +- app/templates/auth/login.html.j2 | 2 +- app/templates/auth/register.html.j2 | 2 +- app/templates/auth/reset_password.html.j2 | 2 +- .../auth/reset_password_request.html.j2 | 2 +- app/templates/auth/unconfirmed.html.j2 | 2 +- app/templates/base.html.j2 | 10 +- app/templates/corpora/add_corpus.html.j2 | 2 +- app/templates/corpora/add_corpus_file.html.j2 | 6 +- app/templates/corpora/corpus.html.j2 | 25 ++--- app/templates/corpora/corpus_file.html.j2 | 2 +- app/templates/corpora/import_corpus.html.j2 | 5 +- app/templates/jobs/job.html.j2 | 51 +++++----- app/templates/main/dashboard.html.j2 | 95 ++++++++++--------- app/templates/main/faq.html.j2 | 2 +- app/templates/main/index.html.j2 | 2 +- app/templates/main/news.html.j2 | 2 +- app/templates/main/privacy_policy.html.j2 | 2 +- app/templates/main/terms_of_use.html.j2 | 2 +- app/templates/materialize/base.html.j2 | 4 +- .../services/corpus_analysis.html.j2 | 2 +- app/templates/services/file_setup.html.j2 | 5 +- app/templates/services/nlp.html.j2 | 8 +- app/templates/services/ocr.html.j2 | 8 +- .../settings/edit_general_settings.html.j2 | 7 +- 39 files changed, 487 insertions(+), 285 deletions(-) diff --git a/app/static/js/nopaque/App.js b/app/static/js/nopaque/App.js index 9162640a..6bad75e8 100644 --- a/app/static/js/nopaque/App.js +++ b/app/static/js/nopaque/App.js @@ -6,36 +6,46 @@ class App { this.socket.on('users.patch', patch => this.usersPatchHandler(patch)); } - get users() {return this.data.users;} + get users() { + return this.data.users; + } addEventListener(type, listener) { - if (!(type in this.eventListeners)) {throw `Unknown event type: ${type}`;} + if (!(type in this.eventListeners)) { + throw `Unknown event type: ${type}`; + } this.eventListeners[type].push(listener); } flash(message, category) { - let toast, toastCloseActionElement; + let iconPrefix; + let toast; + let toastCloseActionElement; + switch (category) { - case "corpus": - message = `<i class="left material-icons">book</i>${message}`; + case 'corpus': + iconPrefix = '<i class="left material-icons">book</i>'; break; - case "error": - message = `<i class="left material-icons error-color-text">error</i>${message}`; + case 'error': + iconPrefix = '<i class="error-color-text left material-icons">error</i>'; break; - case "job": - message = `<i class="left nopaque-icons">J</i>${message}`; + case 'job': + iconPrefix = '<i class="left nopaque-icons">J</i>'; break; default: - message = `<i class="left material-icons">notifications</i>${message}`; + iconPrefix = '<i class="left material-icons">notifications</i>'; + break; } - toast = M.toast({ - html: ` - <span>${message}</span> - <button class="btn-flat toast-action white-text" data-action="close"> - <i class="material-icons">close</i> - </button> - `.trim() - }); + toast = M.toast( + { + html: ` + <span>${iconPrefix}${message}</span> + <button class="btn-flat toast-action white-text" data-action="close"> + <i class="material-icons">close</i> + </button> + `.trim() + } + ); toastCloseActionElement = toast.el.querySelector('.toast-action[data-action="close"]'); toastCloseActionElement.addEventListener('click', () => {toast.dismiss();}); } @@ -55,8 +65,16 @@ class App { } usersPatchHandler(patch) { - let re, match, userId, ressourceId, jobId, relationship; - for (let operation of patch.filter(operation => operation.op === 'add')) { + let jobId; + let listener; + let match; + let operation; + let re; + let relationship; + let ressourceId; + let userId; + + for (operation of patch.filter(operation => operation.op === 'add')) { re = new RegExp(`^/users/([A-Za-z0-9]*)/corpora/([A-Za-z0-9]*)/(files)`); if (re.test(operation.path)) { [match, userId, ressourceId, relationship] = operation.path.match(re); @@ -75,6 +93,6 @@ class App { } } this.data = jsonpatch.apply_patch(this.data, patch); - for (let listener of this.eventListeners['users.patch']) {listener(patch);} + for (listener of this.eventListeners['users.patch']) {listener(patch);} } } diff --git a/app/static/js/nopaque/JobStatusNotifier.js b/app/static/js/nopaque/JobStatusNotifier.js index 51adf06e..84ccb267 100644 --- a/app/static/js/nopaque/JobStatusNotifier.js +++ b/app/static/js/nopaque/JobStatusNotifier.js @@ -4,7 +4,11 @@ class JobStatusNotifier { } usersPatchHandler(patch) { - let re, filteredPatch, match, jobId; + let filteredPatch; + let jobId; + let match; + let re; + re = new RegExp(`^/users/${this.userId}/jobs/([A-Za-z0-9]*)/status$`) filteredPatch = patch .filter(operation => operation.op === 'replace') diff --git a/app/static/js/nopaque/RessourceDisplays/CorpusDisplay.js b/app/static/js/nopaque/RessourceDisplays/CorpusDisplay.js index 739dde2f..fd6fd72f 100644 --- a/app/static/js/nopaque/RessourceDisplays/CorpusDisplay.js +++ b/app/static/js/nopaque/RessourceDisplays/CorpusDisplay.js @@ -2,34 +2,45 @@ class CorpusDisplay extends RessourceDisplay { constructor(displayElement) { super(displayElement); this.corpusId = displayElement.dataset.corpusId; - for (let exportCorpusTriggerElement of this.displayElement.querySelectorAll('.export-corpus-trigger')) { - exportCorpusTriggerElement.addEventListener('click', () => this.requestCorpusExport()); - } - app.socket.on(`export_corpus_${this.corpusId}`, () => this.downloadCorpus()); } init(user) { let corpus; + corpus = user.corpora[this.corpusId]; this.setCreationDate(corpus.creation_date); this.setDescription(corpus.description); this.setLastEditedDate(corpus.last_edited_date); this.setStatus(corpus.status); this.setTitle(corpus.title); - this.setTokenRatio(corpus.num_tokens, corpus.max_num_tokens); + this.setNumTokens(corpus.num_tokens); } patch(patch) { - let re, filteredPatch; + let filteredPatch; + let operation; + let re; + re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}`); filteredPatch = patch.filter(operation => re.test(operation.path)); - for (let operation of filteredPatch) { + for (operation of filteredPatch) { switch(operation.op) { case 'replace': re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/last_edited_date$`); - if (re.test(operation.path)) {this.setLastEditedDate(operation.value); break;} + if (re.test(operation.path)) { + this.setLastEditedDate(operation.value); + break; + } + re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/num_tokens`); + if (re.test(operation.path)) { + this.numTokens(operation.value); + break; + } re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/status$`); - if (re.test(operation.path)) {this.status$(operation.value); break;} + if (re.test(operation.path)) { + this.status(operation.value); + break; + } break; default: break; @@ -37,55 +48,48 @@ class CorpusDisplay extends RessourceDisplay { } } - requestCorpusExport() { - app.socket.emit('export_corpus', app.users[this.userId].corpora[this.corpusId]); - app.flash('Preparing your corpus export...', 'corpus'); - for (let exportCorpusTriggerElement of this.displayElement.querySelectorAll('.export-corpus-trigger')) {exportCorpusTriggerElement.classList.toggle('disabled', true);} - } - - downloadCorpus() { - let downloadButton; - app.flash('Corpus download is ready!', 'corpus'); - for (let exportCorpusTriggerElement of this.displayElement.querySelectorAll('.export-corpus-trigger')) {exportCorpusTriggerElement.classList.toggle('disabled', false);} - // Little trick to call the download view after ziping has finished - downloadButton = document.createElement('a'); - downloadButton.href = `/corpora/${app.users[this.userId].corpora[this.corpusId]}/download`; - downloadButton.click(); - } - setTitle(title) { - for (let element of this.displayElement.querySelectorAll('.corpus-title')) {this.setElement(element, title);} + this.setElements(this.displayElement.querySelectorAll('.corpus-title'), title); } - setTokenRatio(numTokens, maxNumTokens) { - for (let element of this.displayElement.querySelectorAll('.corpus-token-ratio')) {this.setElement(element, `${numTokens}/${maxNumTokens}`);} + setNumTokens(numTokens) { + this.setElements( + this.displayElement.querySelectorAll('.corpus-token-ratio'), + `${numTokens}/${app.users[this.userId].corpora[this.corpusId].max_num_tokens}` + ); } setDescription(description) { - for (let element of this.displayElement.querySelectorAll('.corpus-description')) {this.setElement(element, description);} + this.setElements(this.displayElement.querySelectorAll('.corpus-description'), description); } setStatus(status) { - for (let element of this.displayElement.querySelectorAll('.analyse-corpus-trigger')) { + let element; + let elements; + + this.setElements(this.displayElement.querySelectorAll('.corpus-status'), status); + elements = this.displayElement.querySelectorAll('.analyse-corpus-trigger') + for (element of elements) { if (['analysing', 'prepared', 'start analysis'].includes(status)) { element.classList.remove('disabled'); } else { element.classList.add('disabled'); } } - for (let element of this.displayElement.querySelectorAll('.build-corpus-trigger')) { + elements = this.displayElement.querySelectorAll('.build-corpus-trigger'); + for (element of elements) { if (status === 'unprepared' && Object.values(app.users[this.userId].corpora[this.corpusId].files).length > 0) { element.classList.remove('disabled'); } else { element.classList.add('disabled'); } } - for (let element of this.displayElement.querySelectorAll('.corpus-status')) {this.setElement(element, status);} - for (let exportCorpusTriggerElement of this.displayElement.querySelectorAll('.export-corpus-trigger')) { - exportCorpusTriggerElement.classList.toggle('disabled', !['prepared', 'start analysis', 'stop analysis'].includes(status)); + elements = this.displayElement.querySelectorAll('.status'); + for (element of elements) { + element.dataset.status = status; } - for (let element of this.displayElement.querySelectorAll('.status')) {element.dataset.status = status;} - for (let element of this.displayElement.querySelectorAll('.status-spinner')) { + elements = this.displayElement.querySelectorAll('.status-spinner'); + for (element of elements) { if (['submitted', 'queued', 'running', 'canceling', 'start analysis', 'stop analysis'].includes(status)) { element.classList.remove('hide'); } else { @@ -95,14 +99,16 @@ class CorpusDisplay extends RessourceDisplay { } setCreationDate(creationDate) { - for (let element of this.displayElement.querySelectorAll('.corpus-creation-date')) { - this.setElement(element, creationDate.toLocaleString("en-US")); - } + this.setElements( + this.displayElement.querySelectorAll('.corpus-creation-date'), + new Date(creationDate).toLocaleString("en-US") + ); } setLastEditedDate(lastEditedDate) { - for (let element of this.displayElement.querySelectorAll('.corpus-end-date')) { - this.setElement(element, lastEditedDate.toLocaleString("en-US")); - } + this.setElements( + this.displayElement.querySelectorAll('.corpus-end-date'), + new Date(lastEditedDate).toLocaleString("en-US") + ); } } diff --git a/app/static/js/nopaque/RessourceDisplays/JobDisplay.js b/app/static/js/nopaque/RessourceDisplays/JobDisplay.js index ac181509..61222693 100644 --- a/app/static/js/nopaque/RessourceDisplays/JobDisplay.js +++ b/app/static/js/nopaque/RessourceDisplays/JobDisplay.js @@ -5,7 +5,9 @@ class JobDisplay extends RessourceDisplay { } init(user) { - let job = user.jobs[this.jobId]; + let job; + + job = user.jobs[this.jobId]; this.setCreationDate(job.creation_date); this.setEndDate(job.creation_date); this.setDescription(job.description); @@ -17,9 +19,13 @@ class JobDisplay extends RessourceDisplay { } usersPatchHandler(patch) { - let re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}`); - let filteredPatch = patch.filter(operation => re.test(operation.path)); - for (let operation of filteredPatch) { + let filteredPatch; + let operation; + let re; + + re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}`); + filteredPatch = patch.filter(operation => re.test(operation.path)); + for (operation of filteredPatch) { switch(operation.op) { case 'replace': re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}/end_date$`); @@ -40,26 +46,33 @@ class JobDisplay extends RessourceDisplay { } setTitle(title) { - for (let element of this.displayElement.querySelectorAll('.job-title')) {this.setElement(element, title);} + this.setElements(this.displayElement.querySelectorAll('.job-title'), title); } setDescription(description) { - for (let element of this.displayElement.querySelectorAll('.job-description')) {this.setElement(element, description);} + this.setElements(this.displayElement.querySelectorAll('.job-description'), description); } setStatus(status) { - for (let element of this.displayElement.querySelectorAll('.job-status')) { - this.setElement(element, status); + let element; + let elements; + + this.setElements(this.displayElement.querySelectorAll('.job-status'), status); + + elements = this.displayElement.querySelectorAll('.status'); + for (element of elements) { + element.dataset.status = status; } - for (let element of this.displayElement.querySelectorAll('.status')) {element.dataset.status = status;} - for (let element of this.displayElement.querySelectorAll('.status-spinner')) { + elements = this.displayElement.querySelectorAll('.status-spinner'); + for (element of elements) { if (['complete', 'failed'].includes(status)) { element.classList.add('hide'); } else { element.classList.remove('hide'); } } - for (let element of this.displayElement.querySelectorAll('.restart-job-trigger')) { + elements = this.displayElement.querySelectorAll('.restart-job-trigger'); + for (element of elements) { if (['complete', 'failed'].includes(status)) { element.classList.remove('hide'); } else { @@ -69,26 +82,28 @@ class JobDisplay extends RessourceDisplay { } setCreationDate(creationDate) { - for (let element of this.displayElement.querySelectorAll('.job-creation-date')) { - this.setElement(element, creationDate.toLocaleString('en-US')); - } + this.setElements( + this.displayElement.querySelectorAll('.job-creation-date'), + new Date(creationDate).toLocaleString('en-US') + ); } setEndDate(endDate) { - for (let element of this.displayElement.querySelectorAll('.job-end-date')) { - this.setElement(element, endDate.toLocaleString('en-US')); - } + this.setElements( + this.displayElement.querySelectorAll('.job-end-date'), + new Date(endDate).toLocaleString('en-US') + ); } setService(service) { - for (let element of this.displayElement.querySelectorAll('.job-service')) {this.setElement(element, service);} + this.setElements(this.displayElement.querySelectorAll('.job-service'), service); } setServiceArgs(serviceArgs) { - for (let element of this.displayElement.querySelectorAll('.job-service-args')) {this.setElement(element, serviceArgs);} + this.setElements(this.displayElement.querySelectorAll('.job-service-args'), serviceArgs); } setServiceVersion(serviceVersion) { - for (let element of this.displayElement.querySelectorAll('.job-service-version')) {this.setElement(element, serviceVersion);} + this.setElements(this.displayElement.querySelectorAll('.job-service-version'), serviceVersion); } } diff --git a/app/static/js/nopaque/RessourceDisplays/RessourceDisplay.js b/app/static/js/nopaque/RessourceDisplays/RessourceDisplay.js index c7aebe75..c8c16be1 100644 --- a/app/static/js/nopaque/RessourceDisplays/RessourceDisplay.js +++ b/app/static/js/nopaque/RessourceDisplays/RessourceDisplay.js @@ -3,7 +3,7 @@ class RessourceDisplay { this.displayElement = displayElement; this.userId = this.displayElement.dataset.userId; app.addEventListener('users.patch', patch => this.usersPatchHandler(patch)); - app.getUserById(this.userId).then(user => this.init(user), error => {throw JSON.stringify(error);}); + app.getUserById(this.userId).then(user => this.init(user)); } init(user) {throw 'Not implemented';} @@ -21,4 +21,12 @@ class RessourceDisplay { break; } } + + setElements(elements, value) { + let element; + + for (element of elements) { + this.setElement(element, value); + } + } } diff --git a/app/static/js/nopaque/RessourceLists/CorpusFileList.js b/app/static/js/nopaque/RessourceLists/CorpusFileList.js index fdd26fcd..e49ee8fa 100644 --- a/app/static/js/nopaque/RessourceLists/CorpusFileList.js +++ b/app/static/js/nopaque/RessourceLists/CorpusFileList.js @@ -9,14 +9,23 @@ class CorpusFileList extends RessourceList { } onclick(event) { - let corpusFileElement = event.target.closest('tr[data-id]'); - if (corpusFileElement === null) {throw 'Could not locate corpus file element';} - let corpusFileId = corpusFileElement.dataset.id; - let actionButtonElement = event.target.closest('.action-button[data-action]'); - let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; + let action; + let actionButtonElement; + let corpusFileElement; + let corpusFileId; + let deleteModal; + let deleteModalElement; + let tmp; + + corpusFileElement = event.target.closest('tr[data-id]'); + if (corpusFileElement === null) {return;} + corpusFileId = corpusFileElement.dataset.id; + actionButtonElement = event.target.closest('.action-button[data-action]'); + action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; switch (action) { case 'delete': - let deleteModalHTML = ` + tmp = document.createElement('div'); + tmp.innerHTML = ` <div class="modal"> <div class="modal-content"> <h4>Confirm corpus deletion</h4> @@ -28,10 +37,16 @@ class CorpusFileList extends RessourceList { </div> </div> `.trim(); - let deleteModalParentElement = document.querySelector('#modals'); - deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML); - let deleteModalElement = deleteModalParentElement.lastChild; - let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}}); + deleteModalElement = document.querySelector('#modals').appendChild(tmp.firstChild); + deleteModal = M.Modal.init( + deleteModalElement, + { + onCloseEnd: () => { + deleteModal.destroy(); + deleteModalElement.remove(); + } + } + ); deleteModal.open(); break; case 'download': @@ -46,13 +61,22 @@ class CorpusFileList extends RessourceList { } usersPatchHandler(patch) { - let re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/files/([A-Za-z0-9]*)`); - let filteredPatch = patch.filter(operation => re.test(operation.path)); - for (let operation of filteredPatch) { + let corpusFileId; + let filteredPatch; + let match; + let operation; + let re; + let valueName; + + re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/files/([A-Za-z0-9]*)`); + filteredPatch = patch.filter(operation => re.test(operation.path)); + for (operation of filteredPatch) { switch(operation.op) { case 'add': re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/files/([A-Za-z0-9]*)$`); - if (re.test(operation.path)) {this.add(operation.value);} + if (re.test(operation.path)) { + this.add(operation.value); + } break; case 'remove': re = new RegExp(`^/users/${this.userId}/corpora/${this.corpusId}/files/([A-Za-z0-9]*)$`); diff --git a/app/static/js/nopaque/RessourceLists/CorpusList.js b/app/static/js/nopaque/RessourceLists/CorpusList.js index f9c5fead..156623d3 100644 --- a/app/static/js/nopaque/RessourceLists/CorpusList.js +++ b/app/static/js/nopaque/RessourceLists/CorpusList.js @@ -8,14 +8,23 @@ class CorpusList extends RessourceList { } onclick(event) { - let corpusElement = event.target.closest('tr[data-id]'); - if (corpusElement === null) {throw 'Could not locate corpus element';} - let corpusId = corpusElement.dataset.id; - let actionButtonElement = event.target.closest('.action-button[data-action]'); - let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; + let action; + let actionButtonElement; + let corpusElement; + let corpusId; + let deleteModal; + let deleteModalElement; + let tmp; + + corpusElement = event.target.closest('tr[data-id]'); + if (corpusElement === null) {return;} + corpusId = corpusElement.dataset.id; + actionButtonElement = event.target.closest('.action-button[data-action]'); + action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; switch (action) { case 'delete': - let deleteModalHTML = ` + tmp = document.createElement('div'); + tmp.innerHTML = ` <div class="modal"> <div class="modal-content"> <h4>Confirm corpus deletion</h4> @@ -27,10 +36,16 @@ class CorpusList extends RessourceList { </div> </div> `.trim(); - let deleteModalParentElement = document.querySelector('#modals'); - deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML); - let deleteModalElement = deleteModalParentElement.lastChild; - let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}}); + deleteModalElement = document.querySelector('#modals').appendChild(tmp.firstChild); + deleteModal = M.Modal.init( + deleteModalElement, + { + onCloseEnd: () => { + deleteModal.destroy(); + deleteModalElement.remove(); + } + } + ); deleteModal.open(); break; case 'view': @@ -42,9 +57,16 @@ class CorpusList extends RessourceList { } usersPatchHandler(patch) { - let re = new RegExp(`^/users/${this.userId}/corpora/([A-Za-z0-9]*)`); - let filteredPatch = patch.filter(operation => re.test(operation.path)); - for (let operation of filteredPatch) { + let corpusId; + let filteredPatch; + let match; + let operation; + let re; + let valueName; + + re = new RegExp(`^/users/${this.userId}/corpora/([A-Za-z0-9]*)`); + filteredPatch = patch.filter(operation => re.test(operation.path)); + for (operation of filteredPatch) { switch(operation.op) { case 'add': re = new RegExp(`^/users/${this.userId}/corpora/([A-Za-z0-9]*)$`); @@ -53,14 +75,14 @@ class CorpusList extends RessourceList { case 'remove': re = new RegExp(`^/users/${this.userId}/corpora/([A-Za-z0-9]*)$`); if (re.test(operation.path)) { - let [match, corpusId] = operation.path.match(re); + [match, corpusId] = operation.path.match(re); this.remove(corpusId); } break; case 'replace': re = new RegExp(`^/users/${this.userId}/corpora/([A-Za-z0-9]*)/(status|description|title)$`); if (re.test(operation.path)) { - let [match, corpusId, valueName] = operation.path.match(re); + [match, corpusId, valueName] = operation.path.match(re); this.replace(corpusId, valueName, operation.value); } break; diff --git a/app/static/js/nopaque/RessourceLists/JobInputList.js b/app/static/js/nopaque/RessourceLists/JobInputList.js index 1a919552..4fed368e 100644 --- a/app/static/js/nopaque/RessourceLists/JobInputList.js +++ b/app/static/js/nopaque/RessourceLists/JobInputList.js @@ -9,12 +9,17 @@ class JobInputList extends RessourceList { } onclick(event) { - let jobInputElement = event.target.closest('tr[data-id]'); + let jobInputElement; + let jobInputId; + let action; + let actionButtonElement; + + jobInputElement = event.target.closest('tr[data-id]'); if (jobInputElement === null) {return;} - let jobInputId = jobInputElement.dataset.id; - let actionButtonElement = event.target.closest('.action-button[data-action]'); + jobInputId = jobInputElement.dataset.id; + actionButtonElement = event.target.closest('.action-button[data-action]'); if (actionButtonElement === null) {return;} - let action = actionButtonElement.dataset.action; + action = actionButtonElement.dataset.action; switch (action) { case 'download': window.location.href = `/jobs/${this.jobId}/inputs/${jobInputId}/download`; diff --git a/app/static/js/nopaque/RessourceLists/JobList.js b/app/static/js/nopaque/RessourceLists/JobList.js index 3c21abcb..9dc19ec6 100644 --- a/app/static/js/nopaque/RessourceLists/JobList.js +++ b/app/static/js/nopaque/RessourceLists/JobList.js @@ -8,14 +8,23 @@ class JobList extends RessourceList { } onclick(event) { - let jobElement = event.target.closest('tr[data-id]'); - if (jobElement === null) {throw 'Could not locate job element';} - let jobId = jobElement.dataset.id; - let actionButtonElement = event.target.closest('.action-button[data-action]'); - let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; + let action; + let actionButtonElement; + let deleteModal; + let deleteModalElement; + let jobElement; + let jobId; + let tmp; + + jobElement = event.target.closest('tr[data-id]'); + if (jobElement === null) {return;} + jobId = jobElement.dataset.id; + actionButtonElement = event.target.closest('.action-button[data-action]'); + action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; switch (action) { case 'delete': - let deleteModalHTML = ` + tmp = document.createElement('div'); + tmp.innerHTML = ` <div class="modal"> <div class="modal-content"> <h4>Confirm job deletion</h4> @@ -27,10 +36,16 @@ class JobList extends RessourceList { </div> </div> `.trim(); - let deleteModalParentElement = document.querySelector('#modals'); - deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML); - let deleteModalElement = deleteModalParentElement.lastChild; - let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}}); + deleteModalElement = document.querySelector('#modals').appendChild(tmp.firstChild); + deleteModal = M.Modal.init( + deleteModalElement, + { + onCloseEnd: () => { + deleteModal.destroy(); + deleteModalElement.remove(); + } + } + ); deleteModal.open(); break; case 'view': @@ -42,25 +57,34 @@ class JobList extends RessourceList { } usersPatchHandler(patch) { - let re = new RegExp(`^/users/${this.userId}/jobs/([A-Za-z0-9]*)`); - let filteredPatch = patch.filter(operation => re.test(operation.path)); - for (let operation of filteredPatch) { + let filteredPatch; + let jobId; + let match; + let operation; + let re; + let valueName; + + re = new RegExp(`^/users/${this.userId}/jobs/([A-Za-z0-9]*)`); + filteredPatch = patch.filter(operation => re.test(operation.path)); + for (operation of filteredPatch) { switch(operation.op) { case 'add': re = new RegExp(`^/users/${this.userId}/jobs/([A-Za-z0-9]*)$`); - if (re.test(operation.path)) {this.add(operation.value);} + if (re.test(operation.path)) { + this.add(operation.value); + } break; case 'remove': re = new RegExp(`^/users/${this.userId}/jobs/([A-Za-z0-9]*)$`); if (re.test(operation.path)) { - let [match, jobId] = operation.path.match(re); + [match, jobId] = operation.path.match(re); this.remove(jobId); } break; case 'replace': re = new RegExp(`^/users/${this.userId}/jobs/([A-Za-z0-9]*)/(service|status|description|title)$`); if (re.test(operation.path)) { - let [match, jobId, valueName] = operation.path.match(re); + [match, jobId, valueName] = operation.path.match(re); this.replace(jobId, valueName, operation.value); } break; diff --git a/app/static/js/nopaque/RessourceLists/JobResultList.js b/app/static/js/nopaque/RessourceLists/JobResultList.js index e7410157..0dab71cc 100644 --- a/app/static/js/nopaque/RessourceLists/JobResultList.js +++ b/app/static/js/nopaque/RessourceLists/JobResultList.js @@ -9,12 +9,17 @@ class JobResultList extends RessourceList { } onclick(event) { - let jobResultElement = event.target.closest('tr[data-id]'); + let action; + let actionButtonElement; + let jobResultElement; + let jobResultId; + + jobResultElement = event.target.closest('tr[data-id]'); if (jobResultElement === null) {return;} - let jobResultId = jobResultElement.dataset.id; - let actionButtonElement = event.target.closest('.action-button[data-action]'); + jobResultId = jobResultElement.dataset.id; + actionButtonElement = event.target.closest('.action-button[data-action]'); if (actionButtonElement === null) {return;} - let action = actionButtonElement.dataset.action; + action = actionButtonElement.dataset.action; switch (action) { case 'download': window.location.href = `/jobs/${this.jobId}/results/${jobResultId}`; @@ -25,13 +30,19 @@ class JobResultList extends RessourceList { } usersPatchHandler(patch) { - let re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}/results/([A-Za-z0-9]*)`); - let filteredPatch = patch.filter(operation => re.test(operation.path)); - for (let operation of filteredPatch) { + let filteredPatch; + let operation; + let re; + + re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}/results/([A-Za-z0-9]*)`); + filteredPatch = patch.filter(operation => re.test(operation.path)); + for (operation of filteredPatch) { switch(operation.op) { case 'add': re = new RegExp(`^/users/${this.userId}/jobs/${this.jobId}/results/([A-Za-z0-9]*)$`); - if (re.test(operation.path)) {this.add(operation.value);} + if (re.test(operation.path)) { + this.add(operation.value); + } break; default: break; @@ -41,6 +52,7 @@ class JobResultList extends RessourceList { preprocessRessource(jobResult) { let description; + if (jobResult.filename.endsWith('.pdf.zip')) { description = 'PDF files with text layer'; } else if (jobResult.filename.endsWith('.txt.zip')) { diff --git a/app/static/js/nopaque/RessourceLists/QueryResultList.js b/app/static/js/nopaque/RessourceLists/QueryResultList.js index c64361b5..832a482d 100644 --- a/app/static/js/nopaque/RessourceLists/QueryResultList.js +++ b/app/static/js/nopaque/RessourceLists/QueryResultList.js @@ -8,14 +8,23 @@ class QueryResultList extends RessourceList { } onclick(event) { - let queryResultElement = event.target.closest('tr[data-id]'); + let action; + let actionButtonElement; + let deleteModal; + let deleteModalElement; + let queryResultElement; + let queryResultId; + let tmp; + + queryResultElement = event.target.closest('tr[data-id]'); if (queryResultElement === null) {return;} - let queryResultId = queryResultElement.dataset.id; - let actionButtonElement = event.target.closest('.action-button[data-action]'); - let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; + queryResultId = queryResultElement.dataset.id; + actionButtonElement = event.target.closest('.action-button[data-action]'); + action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; switch (action) { case 'delete': - let deleteModalHTML = ` + tmp = document.createElement('div'); + tmp.innerHTML = ` <div class="modal"> <div class="modal-content"> <h4>Confirm query result deletion</h4> @@ -27,10 +36,16 @@ class QueryResultList extends RessourceList { </div> </div> `.trim(); - let deleteModalParentElement = document.querySelector('#modals'); - deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML); - let deleteModalElement = deleteModalParentElement.lastChild; - let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}}); + deleteModalElement = document.querySelector('#modals').appendChild(tmp.firstChild); + deleteModal = M.Modal.init( + deleteModalElement, + { + onCloseEnd: () => { + deleteModal.destroy(); + deleteModalElement.remove(); + } + } + ); deleteModal.open(); break; case 'view': @@ -42,25 +57,34 @@ class QueryResultList extends RessourceList { } usersPatchHandler(patch) { - let re = new RegExp(`^/users/${this.userId}/query_results/([A-Za-z0-9]*)`); - let filteredPatch = patch.filter(operation => re.test(operation.path)); - for (let operation of filteredPatch) { + let filteredPatch; + let match; + let operation; + let queryResultId; + let re; + let valueName; + + re = new RegExp(`^/users/${this.userId}/query_results/([A-Za-z0-9]*)`); + filteredPatch = patch.filter(operation => re.test(operation.path)); + for (operation of filteredPatch) { switch(operation.op) { case 'add': re = new RegExp(`^/users/${this.userId}/query_results/([A-Za-z0-9]*)$`); - if (re.test(operation.path)) {this.add(operation.value);} + if (re.test(operation.path)) { + this.add(operation.value); + } break; case 'remove': re = new RegExp(`^/users/${this.userId}/query_results/([A-Za-z0-9]*)$`); if (re.test(operation.path)) { - let [match, queryResultId] = operation.path.match(re); + [match, queryResultId] = operation.path.match(re); this.remove(queryResultId); } break; case 'replace': re = new RegExp(`^/users/${this.userId}/query_results/([A-Za-z0-9]*)/(corpus_title|description|query|title)$`); if (re.test(operation.path)) { - let [match, queryResultId, valueName] = operation.path.match(re); + [match, queryResultId, valueName] = operation.path.match(re); this.replace(queryResultId, valueName, operation.value); } break; diff --git a/app/static/js/nopaque/RessourceLists/UserList.js b/app/static/js/nopaque/RessourceLists/UserList.js index 04100d25..24b26ad3 100644 --- a/app/static/js/nopaque/RessourceLists/UserList.js +++ b/app/static/js/nopaque/RessourceLists/UserList.js @@ -8,14 +8,23 @@ class UserList extends RessourceList { } onclick(event) { - let userElement = event.target.closest('tr[data-id]'); + let action; + let actionButtonElement; + let deleteModal; + let deleteModalElement; + let tmp; + let userElement; + let userId; + + userElement = event.target.closest('tr[data-id]'); if (userElement === null) {return;} - let userId = userElement.dataset.id; - let actionButtonElement = event.target.closest('.action-button[data-action]'); - let action = (actionButtonElement === null) ? 'view' : actionButtonElement.dataset.action; + userId = userElement.dataset.id; + actionButtonElement = event.target.closest('.action-button[data-action]'); + action = (actionButtonElement === null) ? 'view' : actionButtonElement.dataset.action; switch (action) { case 'delete': - let deleteModalHTML = ` + tmp = document.createElement('div'); + tmp.innerHTML = ` <div class="modal"> <div class="modal-content"> <h4>Confirm user deletion</h4> @@ -27,10 +36,16 @@ class UserList extends RessourceList { </div> </div> `.trim(); - let deleteModalParentElement = document.querySelector('#modals'); - deleteModalParentElement.insertAdjacentHTML('beforeend', deleteModalHTML); - let deleteModalElement = deleteModalParentElement.lastChild; - let deleteModal = M.Modal.init(deleteModalElement, {onCloseEnd: () => {deleteModal.destroy(); deleteModalElement.remove();}}); + deleteModalElement = document.querySelector('#modals').appendChild(tmp.firstChild); + deleteModal = M.Modal.init( + deleteModalElement, + { + onCloseEnd: () => { + deleteModal.destroy(); + deleteModalElement.remove(); + } + } + ); deleteModal.open(); break; case 'edit': @@ -50,7 +65,7 @@ class UserList extends RessourceList { id_: user.id, username: user.username, email: user.email, - last_seen: user.last_seen.toLocaleString("en-US"), + last_seen: new Date(user.last_seen).toLocaleString("en-US"), role: user.role.name }; } diff --git a/app/templates/admin/edit_user.html.j2 b/app/templates/admin/edit_user.html.j2 index 89a73d03..d824c112 100644 --- a/app/templates/admin/edit_user.html.j2 +++ b/app/templates/admin/edit_user.html.j2 @@ -68,4 +68,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/admin/user.html.j2 b/app/templates/admin/user.html.j2 index 7122e58a..3bc9b1d6 100644 --- a/app/templates/admin/user.html.j2 +++ b/app/templates/admin/user.html.j2 @@ -92,9 +92,11 @@ </div> </div> </div> +{% endblock page_content %} -<!-- Modals --> +{% block modals %} +{{ super() }} <div id="delete-user-modal" class="modal"> <div class="modal-content"> <h3>Delete user</h3> @@ -105,8 +107,7 @@ <a href="{{ url_for('.delete_user', user_id=user.id) }}" class="modal-close waves-effect waves-light btn red"><i class="material-icons left">delete</i>Delete</a> </div> </div> -{% endblock %} - +{% endblock modals %} {% block scripts %} {{ super() }} diff --git a/app/templates/admin/users.html.j2 b/app/templates/admin/users.html.j2 index e8ffac29..8c1e09c1 100644 --- a/app/templates/admin/users.html.j2 +++ b/app/templates/admin/users.html.j2 @@ -35,7 +35,7 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} {% block scripts %} {{ super() }} diff --git a/app/templates/auth/login.html.j2 b/app/templates/auth/login.html.j2 index 58fe45b3..aea71382 100644 --- a/app/templates/auth/login.html.j2 +++ b/app/templates/auth/login.html.j2 @@ -52,4 +52,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/auth/register.html.j2 b/app/templates/auth/register.html.j2 index e1c7186f..99548a1e 100644 --- a/app/templates/auth/register.html.j2 +++ b/app/templates/auth/register.html.j2 @@ -45,4 +45,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/auth/reset_password.html.j2 b/app/templates/auth/reset_password.html.j2 index 376795e1..4be59edf 100644 --- a/app/templates/auth/reset_password.html.j2 +++ b/app/templates/auth/reset_password.html.j2 @@ -29,4 +29,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/auth/reset_password_request.html.j2 b/app/templates/auth/reset_password_request.html.j2 index 66d5776d..b91cd59b 100644 --- a/app/templates/auth/reset_password_request.html.j2 +++ b/app/templates/auth/reset_password_request.html.j2 @@ -28,4 +28,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/auth/unconfirmed.html.j2 b/app/templates/auth/unconfirmed.html.j2 index 89d643ac..db9bf8c4 100644 --- a/app/templates/auth/unconfirmed.html.j2 +++ b/app/templates/auth/unconfirmed.html.j2 @@ -23,4 +23,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/base.html.j2 b/app/templates/base.html.j2 index 7a1c9fa9..dbecd35e 100644 --- a/app/templates/base.html.j2 +++ b/app/templates/base.html.j2 @@ -32,13 +32,13 @@ {% block main_attribs %} class="background-color"{% endblock main_attribs %} {% block main %} {% block page_content %}{% endblock page_content %} -{% block modals %} <div id="modals"> -{% if current_user.is_authenticated %} -{% include "_roadmap.html.j2" %} -{% endif %} + {% block modals %} + {% if current_user.is_authenticated %} + {% include "_roadmap.html.j2" %} + {% endif %} + {% endblock modals %} </div> -{% endblock modals %} {% endblock main %} {% block footer_attribs %} class="page-footer primary-variant-color"{% endblock footer_attribs %} diff --git a/app/templates/corpora/add_corpus.html.j2 b/app/templates/corpora/add_corpus.html.j2 index a44bb990..9d7f24e4 100644 --- a/app/templates/corpora/add_corpus.html.j2 +++ b/app/templates/corpora/add_corpus.html.j2 @@ -38,4 +38,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/corpora/add_corpus_file.html.j2 b/app/templates/corpora/add_corpus_file.html.j2 index da4bb27d..fe0320de 100644 --- a/app/templates/corpora/add_corpus_file.html.j2 +++ b/app/templates/corpora/add_corpus_file.html.j2 @@ -71,7 +71,11 @@ </div> </div> </div> +{% endblock page_content %} + +{% block modals %} +{{ super() }} <div id="progress-modal" class="modal"> <div class="modal-content"> <h4><i class="material-icons prefix">file_upload</i> Uploading file...</h4> @@ -83,4 +87,4 @@ <a href="#!" class="modal-close waves-effect waves-light btn red abort-request">Cancel</a> </div> </div> -{% endblock %} +{% endblock modals %} diff --git a/app/templates/corpora/corpus.html.j2 b/app/templates/corpora/corpus.html.j2 index c6c7702f..1d455eda 100644 --- a/app/templates/corpora/corpus.html.j2 +++ b/app/templates/corpora/corpus.html.j2 @@ -70,17 +70,6 @@ <a class="btn modal-trigger red waves-effect waves-light" data-target="delete-corpus-modal"><i class="material-icons left">delete</i>Delete</a> </div> </div> - - <div id="delete-corpus-modal" class="modal"> - <div class="modal-content"> - <h4>Confirm corpus deletion</h4> - <p>Do you really want to delete the corpus <span class="corpus-title"></span>? All files will be permanently deleted!</p> - </div> - <div class="modal-footer"> - <a class="btn modal-close waves-effect waves-light" href="#!">Cancel</a> - <a class="btn modal-close red waves-effect waves-light" href="{{ url_for('corpora.delete_corpus', corpus_id=corpus.id) }}"><i class="material-icons left">delete</i>Delete</a> - </div> - </div> </div> <div class="col s12" id="corpus-files" data-corpus-id="{{ corpus.hashid }}" data-user-id="{{ corpus.user.hashid }}"> @@ -115,6 +104,20 @@ </div> {% endblock page_content %} +{% block modals %} +{{ super() }} +<div id="delete-corpus-modal" class="modal"> + <div class="modal-content"> + <h4>Confirm corpus deletion</h4> + <p>Do you really want to delete the corpus <span class="corpus-title"></span>? All files will be permanently deleted!</p> + </div> + <div class="modal-footer"> + <a class="btn modal-close waves-effect waves-light" href="#!">Cancel</a> + <a class="btn modal-close red waves-effect waves-light" href="{{ url_for('corpora.delete_corpus', corpus_id=corpus.id) }}"><i class="material-icons left">delete</i>Delete</a> + </div> +</div> +{% endblock modals %} + {% block scripts %} {{ super() }} <script> diff --git a/app/templates/corpora/corpus_file.html.j2 b/app/templates/corpora/corpus_file.html.j2 index df474606..53ac550e 100644 --- a/app/templates/corpora/corpus_file.html.j2 +++ b/app/templates/corpora/corpus_file.html.j2 @@ -48,4 +48,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/corpora/import_corpus.html.j2 b/app/templates/corpora/import_corpus.html.j2 index 68bfc186..d2322fd7 100644 --- a/app/templates/corpora/import_corpus.html.j2 +++ b/app/templates/corpora/import_corpus.html.j2 @@ -43,7 +43,10 @@ </div> </div> </div> +{% endblock page_content %} +{% block modals %} +{{ super() }} <div id="progress-modal" class="modal"> <div class="modal-content"> <h4><i class="material-icons prefix">file_upload</i> Uploading file...</h4> @@ -55,4 +58,4 @@ <a href="#!" class="modal-close waves-effect waves-light btn red abort-request">Cancel</a> </div> </div> -{% endblock %} +{% endblock modals %} diff --git a/app/templates/jobs/job.html.j2 b/app/templates/jobs/job.html.j2 index 344794bd..2712b6ac 100644 --- a/app/templates/jobs/job.html.j2 +++ b/app/templates/jobs/job.html.j2 @@ -85,30 +85,6 @@ <a class="btn modal-trigger red waves-effect waves-light" data-target="delete-job-modal"><i class="material-icons left">delete</i>Delete</a> </div> </div> - - <div id="delete-job-modal" class="modal"> - <div class="modal-content"> - <h4>Confirm deletion</h4> - <p>Do you really want to delete the job <span class="job-title"></span>? All associated files will be permanently deleted.</p> - </div> - <div class="modal-footer"> - <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a> - <a class="btn modal-close red waves-effect waves-light" href="{{ url_for('jobs.delete_job', job_id=job.id) }}"><i class="material-icons left">delete</i>Delete</a> - </div> - </div> - - {% if current_user.is_administrator() %} - <div id="restart-job-modal" class="modal"> - <div class="modal-content"> - <h4>Confirm restart</h4> - <p>Do you really want to restart the job <span class="job-title"></span>? All log and result files will be permanently deleted.</p> - </div> - <div class="modal-footer"> - <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a> - <a class="btn modal-close red waves-effect waves-light" href="{{ url_for('jobs.restart', job_id=job.id) }}"><i class="material-icons left">restart</i>Restart</a> - </div> - </div> - {% endif %} </div> <div class="col s12" id="job-inputs" data-job-id="{{ job.hashid }}" data-user-id="{{ job.user.hashid }}"> @@ -165,6 +141,33 @@ </div> {% endblock page_content %} +{% block modals %} +{{ super() }} +<div id="delete-job-modal" class="modal"> + <div class="modal-content"> + <h4>Confirm deletion</h4> + <p>Do you really want to delete the job <span class="job-title"></span>? All associated files will be permanently deleted.</p> + </div> + <div class="modal-footer"> + <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a> + <a class="btn modal-close red waves-effect waves-light" href="{{ url_for('jobs.delete_job', job_id=job.id) }}"><i class="material-icons left">delete</i>Delete</a> + </div> +</div> + +{% if current_user.is_administrator() %} +<div id="restart-job-modal" class="modal"> + <div class="modal-content"> + <h4>Confirm restart</h4> + <p>Do you really want to restart the job <span class="job-title"></span>? All log and result files will be permanently deleted.</p> + </div> + <div class="modal-footer"> + <a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a> + <a class="btn modal-close red waves-effect waves-light" href="{{ url_for('jobs.restart', job_id=job.id) }}"><i class="material-icons left">restart</i>Restart</a> + </div> +</div> +{% endif %} +{% endblock modals %} + {% block scripts %} {{ super() }} <script> diff --git a/app/templates/main/dashboard.html.j2 b/app/templates/main/dashboard.html.j2 index 1492caf7..8872efca 100644 --- a/app/templates/main/dashboard.html.j2 +++ b/app/templates/main/dashboard.html.j2 @@ -119,58 +119,61 @@ <p><a class="modal-trigger waves-effect waves-light btn" href="#" data-target="new-job-modal"><i class="material-icons left">add</i>New job</a></p> </div> </div> + </div> + </div> +</div> +{% endblock page_content %} - <div id="new-job-modal" class="modal"> - <div class="modal-content"> - <h4>Select a service</h4> - <p> </p> - <div class="row"> - <div class="col s12 m4"> - <div class="card-panel center-align hoverable"> - <br> - <a href="{{ url_for('services.service', service='file-setup') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);"> - <i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i> - </a> - <br><br> - <p class="service-color-text darken" data-service="file-setup"><b>File setup</b></p> - <p class="light">Digital copies of text based research data (books, letters, etc.) often comprise various files and formats. nopaque converts and merges those files to facilitate further processing and the application of other services.</p> - <a href="{{ url_for('services.service', service='file-setup') }}" class="waves-effect waves-light btn service-color darken" data-service="file-setup">Create Job</a> - </div> - </div> - <div class="col s12 m4"> - <div class="card-panel center-align hoverable"> - <br> - <a href="{{ url_for('services.service', service='ocr') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);"> - <i class="nopaque-icons service-color darken service-icon" data-service="ocr" style="font-size: 2.5rem;"></i> - </a> - <br><br> - <p class="service-color-text darken" data-service="ocr"><b>Optical Character Recognition</b></p> - <p class="light">nopaque converts your image data – like photos or scans – into text data through a process called OCR. This step enables you to proceed with further computational analysis of your documents.</p> - <a href="{{ url_for('services.service', service='ocr') }}" class="waves-effect waves-light btn service-color darken" data-service="ocr">Create Job</a> - </div> - </div> - <div class="col s12 m4"> - <div class="card-panel center-align hoverable"> - <br> - <a href="{{ url_for('services.service', service='nlp') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);"> - <i class="nopaque-icons service-color darken service-icon" data-service="nlp" style="font-size: 2.5rem;"></i> - </a> - <br><br> - <p class="service-color-text darken" data-service="nlp"><b>Natural Language Processing</b></p> - <p class="light">By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from your text.</p> - <a href="{{ url_for('services.service', service='nlp') }}" class="waves-effect waves-light btn service-color darken" data-service="nlp">Create Job</a> - </div> - </div> +{% block modals %} +{{ super() }} +<div id="new-job-modal" class="modal"> + <div class="modal-content"> + <h4>Select a service</h4> + <p> </p> + <div class="row"> + <div class="col s12 m4"> + <div class="card-panel center-align hoverable"> + <br> + <a href="{{ url_for('services.service', service='file-setup') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);"> + <i class="nopaque-icons service-color darken service-icon" data-service="file-setup"></i> + </a> + <br><br> + <p class="service-color-text darken" data-service="file-setup"><b>File setup</b></p> + <p class="light">Digital copies of text based research data (books, letters, etc.) often comprise various files and formats. nopaque converts and merges those files to facilitate further processing and the application of other services.</p> + <a href="{{ url_for('services.service', service='file-setup') }}" class="waves-effect waves-light btn service-color darken" data-service="file-setup">Create Job</a> + </div> + </div> + <div class="col s12 m4"> + <div class="card-panel center-align hoverable"> + <br> + <a href="{{ url_for('services.service', service='ocr') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);"> + <i class="nopaque-icons service-color darken service-icon" data-service="ocr" style="font-size: 2.5rem;"></i> + </a> + <br><br> + <p class="service-color-text darken" data-service="ocr"><b>Optical Character Recognition</b></p> + <p class="light">nopaque converts your image data – like photos or scans – into text data through a process called OCR. This step enables you to proceed with further computational analysis of your documents.</p> + <a href="{{ url_for('services.service', service='ocr') }}" class="waves-effect waves-light btn service-color darken" data-service="ocr">Create Job</a> + </div> + </div> + <div class="col s12 m4"> + <div class="card-panel center-align hoverable"> + <br> + <a href="{{ url_for('services.service', service='nlp') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);"> + <i class="nopaque-icons service-color darken service-icon" data-service="nlp" style="font-size: 2.5rem;"></i> + </a> + <br><br> + <p class="service-color-text darken" data-service="nlp"><b>Natural Language Processing</b></p> + <p class="light">By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from your text.</p> + <a href="{{ url_for('services.service', service='nlp') }}" class="waves-effect waves-light btn service-color darken" data-service="nlp">Create Job</a> </div> - </div> - <div class="modal-footer"> - <a href="#!" class="modal-close waves-effect waves-light btn-flat">Close</a> - </div> </div> </div> </div> + <div class="modal-footer"> + <a href="#!" class="modal-close waves-effect waves-light btn-flat">Close</a> + </div> </div> -{% endblock %} +{% endblock modals %} {% block scripts %} {{ super() }} diff --git a/app/templates/main/faq.html.j2 b/app/templates/main/faq.html.j2 index 308534d2..86dde843 100644 --- a/app/templates/main/faq.html.j2 +++ b/app/templates/main/faq.html.j2 @@ -53,4 +53,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/main/index.html.j2 b/app/templates/main/index.html.j2 index 6165a4b3..94db3551 100644 --- a/app/templates/main/index.html.j2 +++ b/app/templates/main/index.html.j2 @@ -215,4 +215,4 @@ <img src="{{ url_for('static', filename='images/parallax_lq/05_chapter_book_text_tale.jpg') }}" alt=""> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/main/news.html.j2 b/app/templates/main/news.html.j2 index 8e3cbfd4..568cf706 100644 --- a/app/templates/main/news.html.j2 +++ b/app/templates/main/news.html.j2 @@ -48,4 +48,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/main/privacy_policy.html.j2 b/app/templates/main/privacy_policy.html.j2 index 1b7c1c6d..ff22b10a 100644 --- a/app/templates/main/privacy_policy.html.j2 +++ b/app/templates/main/privacy_policy.html.j2 @@ -152,4 +152,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/main/terms_of_use.html.j2 b/app/templates/main/terms_of_use.html.j2 index f84a2941..baedd0a2 100644 --- a/app/templates/main/terms_of_use.html.j2 +++ b/app/templates/main/terms_of_use.html.j2 @@ -109,4 +109,4 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} diff --git a/app/templates/materialize/base.html.j2 b/app/templates/materialize/base.html.j2 index 28b03d45..a7de0e2d 100644 --- a/app/templates/materialize/base.html.j2 +++ b/app/templates/materialize/base.html.j2 @@ -1,7 +1,7 @@ {% block doc %} <!DOCTYPE html> <html{% block html_attribs %}{% endblock html_attribs %}> -{% block html %} + {% block html %} <head> {% block head %} <title>{% block title %}{{title|default}}{% endblock title %}</title> @@ -40,6 +40,6 @@ {% endblock scripts %} {% endblock body %} </body> -{% endblock html %} + {% endblock html %} </html> {% endblock doc %} diff --git a/app/templates/services/corpus_analysis.html.j2 b/app/templates/services/corpus_analysis.html.j2 index c3c19568..66d880fe 100644 --- a/app/templates/services/corpus_analysis.html.j2 +++ b/app/templates/services/corpus_analysis.html.j2 @@ -88,7 +88,7 @@ </div> </div> </div> -{% endblock %} +{% endblock page_content %} {% block scripts %} {{ super() }} diff --git a/app/templates/services/file_setup.html.j2 b/app/templates/services/file_setup.html.j2 index 65c633f0..1c974a9e 100644 --- a/app/templates/services/file_setup.html.j2 +++ b/app/templates/services/file_setup.html.j2 @@ -65,7 +65,10 @@ </div> </div> </div> +{% endblock page_content %} +{% block modals %} +{{ super() }} <div id="progress-modal" class="modal"> <div class="modal-content"> <h4><i class="material-icons prefix">file_upload</i> Uploading files...</h4> @@ -77,4 +80,4 @@ <a href="#!" class="modal-close waves-effect waves-light btn red abort-request">Cancel</a> </div> </div> -{% endblock %} +{% endblock modals %} diff --git a/app/templates/services/nlp.html.j2 b/app/templates/services/nlp.html.j2 index de95836f..e24d867c 100644 --- a/app/templates/services/nlp.html.j2 +++ b/app/templates/services/nlp.html.j2 @@ -107,7 +107,10 @@ </div> </div> </div> +{% endblock page_content %} +{% block modals %} +{{ super() }} <div id="progress-modal" class="modal"> <div class="modal-content"> <h4><i class="material-icons prefix">file_upload</i> Uploading files...</h4> @@ -119,8 +122,7 @@ <a href="#!" class="modal-close waves-effect waves-light btn red abort-request">Cancel</a> </div> </div> -{% endblock %} - +{% endblock modals %} {% block scripts %} {{ super() }} @@ -132,4 +134,4 @@ window.location.href = url.toString(); }); </script> -{% endblock %} +{% endblock scripts %} diff --git a/app/templates/services/ocr.html.j2 b/app/templates/services/ocr.html.j2 index 12051b9c..7eba0241 100644 --- a/app/templates/services/ocr.html.j2 +++ b/app/templates/services/ocr.html.j2 @@ -134,7 +134,10 @@ </div> </div> </div> +{% endblock page_content %} +{% block modals %} +{{ super() }} <div id="progress-modal" class="modal"> <div class="modal-content"> <h4><i class="material-icons left">file_upload</i>Uploading files...</h4> @@ -146,8 +149,7 @@ <a href="#!" class="modal-close waves-effect waves-light btn red abort-request">Cancel</a> </div> </div> -{% endblock %} - +{% endblock modals %} {% block scripts %} {{ super() }} @@ -159,4 +161,4 @@ window.location.href = url.toString(); }); </script> -{% endblock %} +{% endblock scripts %} diff --git a/app/templates/settings/edit_general_settings.html.j2 b/app/templates/settings/edit_general_settings.html.j2 index 19f487e7..cfae41a6 100644 --- a/app/templates/settings/edit_general_settings.html.j2 +++ b/app/templates/settings/edit_general_settings.html.j2 @@ -64,9 +64,10 @@ </div> </div> </div> +{% endblock page_content %} - -<!-- Modals --> +{% block modals %} +{{ super() }} <div class="modal" id="delete-account-modal"> <div class="modal-content"> <h4>Confirm deletion</h4> @@ -77,4 +78,4 @@ <a href="{{ url_for('.delete') }}" class="btn red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a> </div> </div> -{% endblock page_content %} +{% endblock modals %} -- GitLab