From 77b58d03c37c7b5a01115518ff145cb0aa1ada1c Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Tue, 3 Jan 2023 17:03:47 +0100 Subject: [PATCH] Change List.js integration and rename service-icon css --- app/static/css/colors.scss | 6 +- app/static/css/style.css | 23 +++-- .../js/RessourceLists/CorpusFileList.js | 66 ++++++------- app/static/js/RessourceLists/CorpusList.js | 67 +++++++------ app/static/js/RessourceLists/JobInputList.js | 50 +++++----- app/static/js/RessourceLists/JobList.js | 65 ++++++------- app/static/js/RessourceLists/JobResultList.js | 54 ++++++----- .../js/RessourceLists/PublicUserList.js | 62 +++++++------ app/static/js/RessourceLists/RessourceList.js | 93 ++++++++++--------- .../SpacyNLPPipelineModelList.js | 84 +++++++++-------- .../TesseractOCRPipelineModelList.js | 84 +++++++++-------- app/static/js/RessourceLists/UserList.js | 68 +++++++------- app/templates/_scripts.html.j2 | 19 ++-- app/templates/_sidenav.html.j2 | 10 +- .../contributions/contributions.html.j2 | 6 +- .../create_spacy_nlp_pipeline_model.html.j2 | 2 +- ...reate_tesseract_ocr_pipeline_model.html.j2 | 2 +- app/templates/corpora/analyse_corpus.html.j2 | 2 +- app/templates/jobs/job.html.j2 | 2 +- app/templates/main/dashboard.html.j2 | 6 +- app/templates/main/dashboard2.html.j2 | 6 +- app/templates/main/index.html.j2 | 10 +- .../services/corpus_analysis.html.j2 | 2 +- .../services/file_setup_pipeline.html.j2 | 2 +- .../services/spacy_nlp_pipeline.html.j2 | 2 +- .../services/tesseract_ocr_pipeline.html.j2 | 2 +- .../services/transkribus_htr_pipeline.html.j2 | 2 +- 27 files changed, 413 insertions(+), 384 deletions(-) diff --git a/app/static/css/colors.scss b/app/static/css/colors.scss index 22feeb41..f8f04228 100644 --- a/app/static/css/colors.scss +++ b/app/static/css/colors.scss @@ -201,15 +201,15 @@ $color: ( @each $ressource-name, $color-palette in map-get($color, "status") { @each $key, $color-code in $color-palette { - .#{$ressource-name}-status-color[data-#{$ressource-name}-status="#{$key}"] { + .#{$ressource-name}-status-color[data-status="#{$key}"] { background-color: $color-code !important; } - .#{$ressource-name}-status-color-border[data-#{$ressource-name}-status="#{$key}"] { + .#{$ressource-name}-status-color-border[data-status="#{$key}"] { border-color: $color-code !important; } - .#{$ressource-name}-status-color-text[data-#{$ressource-name}-status="#{$key}"] { + .#{$ressource-name}-status-color-text[data-status="#{$key}"] { color: $color-code !important; } } diff --git a/app/static/css/style.css b/app/static/css/style.css index e0c288b5..ba45e025 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -27,7 +27,7 @@ transform: scale(2); } -.btn-scale-x2 .nopaque-icons.service-icon { +.btn-scale-x2 .nopaque-icons.service-icons { font-size: 2.5rem; } @@ -37,17 +37,20 @@ h1 .nopaque-icons, h2 .nopaque-icons, h3 .nopaque-icons, h4 .nopaque-icons, .tab } -.corpus-status-text {text-transform: lowercase;} -.corpus-status-text[data-corpus-status]:empty:before {content: attr(data-corpus-status);} +.corpus-status-text, .job-status-text {text-transform: lowercase;} +.corpus-status-text[data-status]:empty::before, .job-status-text[data-status]:empty::before {content: attr(data-status);} -.job-status-text {text-transform: lowercase;} -.job-status-text[data-job-status]:empty:before {content: attr(data-job-status);} +.service-scheme[data-service="file-setup-pipeline"] .nopaque-icons.service-icons[data-service="inherit"]:empty::before {content: "E";} +.service-scheme[data-service="tesseract-ocr-pipeline"] .nopaque-icons.service-icons[data-service="inherit"]:empty::before {content: "F";} +.service-scheme[data-service="transkribus-htr-pipeline"] .nopaque-icons.service-icons[data-service="inherit"]:empty::before {content: "F";} +.service-scheme[data-service="spacy-nlp-pipeline"] .nopaque-icons.service-icons[data-service="inherit"]:empty::before {content: "G";} +.service-scheme[data-service="corpus-analysis"] .nopaque-icons.service-icons[data-service="inherit"]:empty::before {content: "H";} -.nopaque-icons.service-icon[data-service="file-setup-pipeline"]:empty:before {content: "E";} -.nopaque-icons.service-icon[data-service="tesseract-ocr-pipeline"]:empty:before {content: "F";} -.nopaque-icons.service-icon[data-service="transkribus-htr-pipeline"]:empty:before {content: "F";} -.nopaque-icons.service-icon[data-service="spacy-nlp-pipeline"]:empty:before {content: "G";} -.nopaque-icons.service-icon[data-service="corpus-analysis"]:empty:before {content: "H";} +.nopaque-icons.service-icons[data-service="file-setup-pipeline"]:empty::before {content: "E";} +.nopaque-icons.service-icons[data-service="tesseract-ocr-pipeline"]:empty::before {content: "F";} +.nopaque-icons.service-icons[data-service="transkribus-htr-pipeline"]:empty::before {content: "F";} +.nopaque-icons.service-icons[data-service="spacy-nlp-pipeline"]:empty::before {content: "G";} +.nopaque-icons.service-icons[data-service="corpus-analysis"]:empty::before {content: "H";} .clickable { cursor: pointer !important; diff --git a/app/static/js/RessourceLists/CorpusFileList.js b/app/static/js/RessourceLists/CorpusFileList.js index a24fcf7e..af68c9dc 100644 --- a/app/static/js/RessourceLists/CorpusFileList.js +++ b/app/static/js/RessourceLists/CorpusFileList.js @@ -6,12 +6,12 @@ class CorpusFileList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +
@@ -28,19 +28,6 @@ class CorpusFileList extends RessourceList { `.trim(); }, - item: ` - - - - - - - - `.trim(), ressourceMapper: (corpusFile) => { return { 'id': corpusFile.id, @@ -51,20 +38,35 @@ class CorpusFileList extends RessourceList { 'title': corpusFile.title }; }, - sortArgs: ['creation-date', {order: 'desc'}], - valueNames: [ - {data: ['id']}, - {data: ['creation-date']}, - 'author', - 'filename', - 'publishing-year', - 'title' - ] + sortParams: ['creation-date', {order: 'desc'}], + listjs: { + item: ` + + + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['creation-date']}, + 'author', + 'filename', + 'publishing-year', + 'title' + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...CorpusFileList.options, ...options}); - this.corpusId = listElement.dataset.corpusId; + constructor(listContainerElement, options={}) { + super(listContainerElement, _.merge({}, CorpusFileList.options, options)); + this.corpusId = listContainerElement.dataset.corpusId; } init(user) { @@ -72,10 +74,12 @@ class CorpusFileList extends RessourceList { } onClick(event) { + let corpusFileElement = event.target.closest('tr'); + if (corpusFileElement === null) {return;} + let corpusFileId = corpusFileElement.dataset.id; + if (corpusFileId === undefined) {return;} let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; - let corpusFileElement = event.target.closest('tr'); - let corpusFileId = corpusFileElement.dataset.id; switch (action) { case 'delete': { Utils.deleteCorpusFileRequest(this.userId, this.corpusId, corpusFileId); diff --git a/app/static/js/RessourceLists/CorpusList.js b/app/static/js/RessourceLists/CorpusList.js index a16b1ce7..fa0fa704 100644 --- a/app/static/js/RessourceLists/CorpusList.js +++ b/app/static/js/RessourceLists/CorpusList.js @@ -1,12 +1,4 @@ class CorpusList extends RessourceList { - static instances = []; - - static getInstance(elem) { - return CorpusList.instances.find((instance) => { - return instance.listjs.list === elem; - }); - } - static autoInit() { for (let corpusListElement of document.querySelectorAll('.corpus-list:not(.no-autoinit)')) { new CorpusList(corpusListElement); @@ -14,12 +6,12 @@ class CorpusList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +
- delete - file_download - send -
+ delete + file_download + send +
@@ -35,17 +27,6 @@ class CorpusList extends RessourceList { `.trim(); }, - item: ` - - - - - - - `.trim(), ressourceMapper: (corpus) => { return { 'id': corpus.id, @@ -55,19 +36,31 @@ class CorpusList extends RessourceList { 'title': corpus.title }; }, - sortArgs: ['creation-date', {order: 'desc'}], - valueNames: [ - {data: ['id']}, - {data: ['creation-date']}, - {name: 'status', attr: 'data-corpus-status'}, - 'description', - 'title' - ] + sortParams: ['creation-date', {order: 'desc'}], + listjs: { + item: ` + + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['creation-date']}, + {name: 'status', attr: 'data-status'}, + 'description', + 'title' + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...CorpusList.options, ...options}); - CorpusList.instances.push(this); + constructor(listContainerElement, options={}) { + super(listContainerElement, _.merge({}, CorpusList.options, options)); } init(user) { @@ -75,10 +68,12 @@ class CorpusList extends RessourceList { } onClick(event) { + let corpusElement = event.target.closest('tr'); + if (corpusElement === null) {return;} + let corpusId = corpusElement.dataset.id; + if (corpusId === undefined) {return;} let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; - let corpusElement = event.target.closest('tr'); - let corpusId = corpusElement.dataset.id; switch (action) { case 'delete-request': { Utils.deleteCorpusRequest(this.userId, corpusId); diff --git a/app/static/js/RessourceLists/JobInputList.js b/app/static/js/RessourceLists/JobInputList.js index 2cd14aa9..069d470e 100644 --- a/app/static/js/RessourceLists/JobInputList.js +++ b/app/static/js/RessourceLists/JobInputList.js @@ -6,12 +6,12 @@ class JobInputList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +
book
- delete - send -
book
+ delete + send +
@@ -25,14 +25,6 @@ class JobInputList extends RessourceList { `.trim(); }, - item: ` - - - - - `.trim(), ressourceMapper: (jobInput) => { return { 'id': jobInput.id, @@ -40,17 +32,27 @@ class JobInputList extends RessourceList { 'filename': jobInput.filename }; }, - sortArgs: ['filename', {order: 'asc'}], - valueNames: [ - {data: ['id']}, - {data: ['creation-date']}, - 'filename' - ] + sortParams: ['filename', {order: 'asc'}], + listjs: { + item: ` + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['creation-date']}, + 'filename' + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...JobInputList.options, ...options}); - this.jobId = listElement.dataset.jobId; + constructor(listContainerElement, options={}) { + super(listContainerElement, _.merge({}, JobInputList.options, options)); + this.jobId = listContainerElement.dataset.jobId; } init(user) { @@ -58,10 +60,12 @@ class JobInputList extends RessourceList { } onClick(event) { + let jobInputElement = event.target.closest('tr'); + if (jobInputElement === null) {return;} + let jobInputId = jobInputElement.dataset.id; + if (jobInputId === undefined) {return;} let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'download' : actionButtonElement.dataset.action; - let jobInputElement = event.target.closest('tr'); - let jobInputId = jobInputElement.dataset.id; switch (action) { case 'download': { window.location.href = `/jobs/${this.jobId}/inputs/${jobInputId}/download`; diff --git a/app/static/js/RessourceLists/JobList.js b/app/static/js/RessourceLists/JobList.js index d6fa7894..3a8c6d8b 100644 --- a/app/static/js/RessourceLists/JobList.js +++ b/app/static/js/RessourceLists/JobList.js @@ -6,12 +6,12 @@ class JobList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +
- file_download -
+ file_download +
@@ -27,44 +27,43 @@ class JobList extends RessourceList { `.trim(); }, - item: ` - - - - - - - `.trim(), ressourceMapper: (job) => { return { 'id': job.id, 'creation-date': job.creation_date, 'description': job.description, 'service': job.service, - 'service-1': job.service, - 'service-2': job.service, 'status': job.status, 'title': job.title }; }, - sortArgs: ['creation-date', {order: 'desc'}], - valueNames: [ - {data: ['id']}, - {data: ['creation-date']}, - {data: ['service']}, - {name: 'service-1', attr: 'data-service'}, - {name: 'service-2', attr: 'data-service'}, - {name: 'status', attr: 'data-job-status'}, - 'description', - 'title' - ] + sortParams: ['creation-date', {order: 'desc'}], + listjs: { + item: ` + + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['creation-date']}, + {data: ['service']}, + {name: 'status', attr: 'data-status'}, + 'description', + 'title' + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...JobList.options, ...options}); + constructor(listContainerElement, options={}) { + super(listContainerElement, _.merge({}, JobList.options, options)); + console.log(this); } init(user) { @@ -72,10 +71,12 @@ class JobList extends RessourceList { } onClick(event) { + let jobElement = event.target.closest('tr'); + if (jobElement === null) {return;} + let jobId = jobElement.dataset.id; + if (jobId === undefined) {return;} let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; - let jobElement = event.target.closest('tr'); - let jobId = jobElement.dataset.id; switch (action) { case 'delete-request': { Utils.deleteJobRequest(this.userId, jobId); diff --git a/app/static/js/RessourceLists/JobResultList.js b/app/static/js/RessourceLists/JobResultList.js index 3623363a..ea7cfc3a 100644 --- a/app/static/js/RessourceLists/JobResultList.js +++ b/app/static/js/RessourceLists/JobResultList.js @@ -6,12 +6,12 @@ class JobResultList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +

- delete - send -

+ delete + send +
@@ -26,15 +26,6 @@ class JobResultList extends RessourceList { `.trim(); }, - item: ` - - - - - - `.trim(), ressourceMapper: (jobResult) => { return { 'id': jobResult.id, @@ -43,18 +34,29 @@ class JobResultList extends RessourceList { 'filename': jobResult.filename }; }, - sortArgs: ['filename', {order: 'asc'}], - valueNames: [ - {data: ['id']}, - {data: ['creation-date']}, - 'description', - 'filename' - ] + sortParams: ['filename', {order: 'asc'}], + listjs: { + item: ` + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['creation-date']}, + 'description', + 'filename' + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...JobResultList.options, ...options}); - this.jobId = listElement.dataset.jobId; + constructor(listContainerElement, options = {}) { + super(listContainerElement, {...JobResultList.options, ...options}); + this.jobId = listContainerElement.dataset.jobId; } init(user) { @@ -62,10 +64,12 @@ class JobResultList extends RessourceList { } onClick(event) { + let jobResultElement = event.target.closest('tr'); + if (jobResultElement === null) {return;} + let jobResultId = jobResultElement.dataset.id; + if (jobResultId === undefined) {return;} let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'download' : actionButtonElement.dataset.action; - let jobResultElement = event.target.closest('tr'); - let jobResultId = jobResultElement.dataset.id; switch (action) { case 'download': { window.location.href = `/jobs/${this.jobId}/results/${jobResultId}/download`; diff --git a/app/static/js/RessourceLists/PublicUserList.js b/app/static/js/RessourceLists/PublicUserList.js index f5c93b8b..2b1b94c8 100644 --- a/app/static/js/RessourceLists/PublicUserList.js +++ b/app/static/js/RessourceLists/PublicUserList.js @@ -6,12 +6,12 @@ class PublicUserList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +
- file_download -
+ file_download +
@@ -30,19 +30,6 @@ class PublicUserList extends RessourceList { `.trim(); }, - item: ` - - - - - - - - - - `.trim(), ressourceMapper: (user) => { return { 'id': user.id, @@ -55,21 +42,36 @@ class PublicUserList extends RessourceList { 'corpora-online': '0' }; }, - sortArgs: ['member-since', {order: 'desc'}], - valueNames: [ - {data: ['id']}, - {data: ['member-since']}, - {name: 'avatar', attr: 'src'}, - 'username', - 'full-name', - 'location', - 'organization', - 'corpora-online' - ] + sortParams: ['member-since', {order: 'desc'}], + listjs: { + item: ` + + + + + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['member-since']}, + {name: 'avatar', attr: 'src'}, + 'username', + 'full-name', + 'location', + 'organization', + 'corpora-online' + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...PublicUserList.options, ...options}); + constructor(listContainerElement, options = {}) { + super(listContainerElement, {...PublicUserList.options, ...options}); } init(users) { diff --git a/app/static/js/RessourceLists/RessourceList.js b/app/static/js/RessourceLists/RessourceList.js index e1f47f2f..8c58ef42 100644 --- a/app/static/js/RessourceLists/RessourceList.js +++ b/app/static/js/RessourceLists/RessourceList.js @@ -16,64 +16,69 @@ class RessourceList { UserList.autoInit(); } - static options = {page: 5, pagination: {innerWindow: 2, outerWindow: 2}}; + static options = { + listContainerInnerHTMLGenerator: null, + ressourceMapper: null, + sortParams: null, + listjs: { + page: 5, + pagination: { + innerWindow: 2, + outerWindow: 2 + } + } + }; - constructor(listElement, options = {}) { - if (!(listElement.hasAttribute('id'))) { + constructor(listContainerElement, options={}) { + let mergedOptions = _.merge({}, RessourceList.options, options); + this.isInitialized = false; + this.listContainerInnerHTMLGenerator = mergedOptions.listContainerInnerHTMLGenerator; + this.ressourceMapper = mergedOptions.ressourceMapper; + this.sortParams = mergedOptions.sortParams; + this.userId = listContainerElement.dataset.userId; + // #region Make sure listElement has an id + if (!listContainerElement.hasAttribute('id')) { let i; for (i = 0; true; i++) { if (document.querySelector(`#ressource-list-${i}`)) {continue;} - listElement.id = `ressource-list-${i}`; + listContainerElement.id = `ressource-list-${i}`; break; } } - options = { - ...RessourceList.options, - ...options + // #endregion + if (this.listContainerInnerHTMLGenerator !== null && listContainerElement.textContent.trim() === '') { + this.listContainerInnerHTMLGenerator(listContainerElement); } - if ('ressourceMapper' in options && typeof options.ressourceMapper === 'function') { - this.ressourceMapper = options.ressourceMapper; - delete options.ressourceMapper; - } - if ('initialHtmlGenerator' in options && typeof options.initialHtmlGenerator === 'function') { - this.initialHtmlGenerator = options.initialHtmlGenerator; - listElement.innerHTML = this.initialHtmlGenerator(listElement.id); - delete options.initialHtmlGenerator; - } - if ('sortArgs' in options) { - this.sortArgs = options.sortArgs; - delete options.sortArgs; - } - this.listjs = new List(listElement, {...RessourceList.options, ...options}); + this.listjs = new List(listContainerElement, mergedOptions.listjs); + this.listjs.list.addEventListener('click', (event) => {this.onClick(event)}); this.listjs.list.innerHTML = ` - `.trim(); - this.userId = this.listjs.listContainer.dataset.userId; - this.listjs.list.addEventListener('click', (event) => {this.onClick(event)}); - this.isInitialized = false; if (this.userId) { app.subscribeUser(this.userId) .then((response) => { @@ -113,12 +118,12 @@ class RessourceList { add(ressources) { let values = Array.isArray(ressources) ? ressources : [ressources]; - if ('ressourceMapper' in this) { + if (this.ressourceMapper !== null) { values = values.map((value) => {return this.ressourceMapper(value);}); } this.listjs.add(values, () => { - if ('sortArgs' in this) { - this.listjs.sort(...this.sortArgs); + if (this.sortParams !== null) { + this.listjs.sort(...this.sortParams); } }); } diff --git a/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js b/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js index d03c79eb..e62428cf 100644 --- a/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js +++ b/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js @@ -6,12 +6,12 @@ class SpaCyNLPPipelineModelList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +
user-image - send -
user-image + send +
-
 
-
-
-
-
-
-
-
-
-
-
-
+
+
+
 
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- Waiting for data... -

This list is not initialized yet.

+
+ Waiting for data... +

This list is not initialized yet.

+
@@ -26,26 +26,6 @@ class SpaCyNLPPipelineModelList extends RessourceList { `.trim(); }, - item: ` - - - - - - - `.trim(), ressourceMapper: (spaCyNLPPipelineModel) => { return { 'id': spaCyNLPPipelineModel.id, @@ -62,25 +42,47 @@ class SpaCyNLPPipelineModelList extends RessourceList { 'is_public': spaCyNLPPipelineModel.is_public ? 'True' : 'False' }; }, - sortArgs: ['creation-date', {order: 'desc'}], - valueNames: [ - {data: ['id']}, - {data: ['creation-date']}, - {name: 'publisher-url', attr: 'href'}, - {name: 'publishing-url', attr: 'href'}, - 'description', - 'publisher', - 'publishing-url-2', - 'publishing-year', - 'title', - 'title-2', - 'version', - {name: 'is_public', attr: 'data-checked'} - ] + sortParams: ['creation-date', {order: 'desc'}], + listjs: { + item: ` + + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['creation-date']}, + {name: 'publisher-url', attr: 'href'}, + {name: 'publishing-url', attr: 'href'}, + 'description', + 'publisher', + 'publishing-url-2', + 'publishing-year', + 'title', + 'title-2', + 'version', + {name: 'is_public', attr: 'data-checked'} + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...SpaCyNLPPipelineModelList.options, ...options}); + constructor(listContainerElement, options = {}) { + super(listContainerElement, {...SpaCyNLPPipelineModelList.options, ...options}); this.listjs.list.addEventListener('change', (event) => {this.onChange(event)}); } diff --git a/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js b/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js index d299af1b..76532fcc 100644 --- a/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js +++ b/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js @@ -6,12 +6,12 @@ class TesseractOCRPipelineModelList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +

()
-
- - -
-
- delete - send -

()
+
+ + +
+
+ delete + send +
@@ -26,26 +26,6 @@ class TesseractOCRPipelineModelList extends RessourceList { `.trim(); }, - item: ` - - - - - - - `.trim(), ressourceMapper: (tesseractOCRPipelineModel) => { return { 'id': tesseractOCRPipelineModel.id, @@ -62,25 +42,47 @@ class TesseractOCRPipelineModelList extends RessourceList { 'is_public': tesseractOCRPipelineModel.is_public ? 'True' : 'False' }; }, - sortArgs: ['creation-date', {order: 'desc'}], - valueNames: [ - {data: ['id']}, - {data: ['creation-date']}, - {name: 'publisher-url', attr: 'href'}, - {name: 'publishing-url', attr: 'href'}, - 'description', - 'publisher', - 'publishing-url-2', - 'publishing-year', - 'title', - 'title-2', - 'version', - {name: 'is_public', attr: 'data-checked'} - ] + sortParams: ['creation-date', {order: 'desc'}], + listjs: { + item: ` + + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['creation-date']}, + {name: 'publisher-url', attr: 'href'}, + {name: 'publishing-url', attr: 'href'}, + 'description', + 'publisher', + 'publishing-url-2', + 'publishing-year', + 'title', + 'title-2', + 'version', + {name: 'is_public', attr: 'data-checked'} + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...TesseractOCRPipelineModelList.options, ...options}); + constructor(listContainerElement, options = {}) { + super(listContainerElement, {...TesseractOCRPipelineModelList.options, ...options}); this.listjs.list.addEventListener('change', (event) => {this.onChange(event)}); } diff --git a/app/static/js/RessourceLists/UserList.js b/app/static/js/RessourceLists/UserList.js index 986685ba..09a25f21 100644 --- a/app/static/js/RessourceLists/UserList.js +++ b/app/static/js/RessourceLists/UserList.js @@ -6,12 +6,12 @@ class UserList extends RessourceList { } static options = { - initialHtmlGenerator: (id) => { - return ` + listContainerInnerHTMLGenerator: (listContainerElement) => { + listContainerElement.innerHTML = `
search - - + +

()
-
- - -
-
- delete - send -

()
+
+ + +
+
+ delete + send +
@@ -29,20 +29,6 @@ class UserList extends RessourceList { `.trim(); }, - item: ` - - - - - - - - - `.trim(), ressourceMapper: (user) => { return { 'id': user.id, @@ -54,20 +40,36 @@ class UserList extends RessourceList { 'role': user.role.name }; }, - sortArgs: ['member-since', {order: 'desc'}], - valueNames: [ - {data: ['id']}, - {data: ['member-since']}, - 'email', - 'id-1', - 'last-seen', - 'role', - 'username' - ] + sortParams: ['member-since', {order: 'desc'}], + listjs: { + item: ` + + + + + + + + + `.trim(), + valueNames: [ + {data: ['id']}, + {data: ['member-since']}, + 'email', + 'id-1', + 'last-seen', + 'role', + 'username' + ] + } }; - constructor(listElement, options = {}) { - super(listElement, {...UserList.options, ...options}); + constructor(listContainerElement, options = {}) { + super(listContainerElement, {...UserList.options, ...options}); } init(users) { @@ -75,10 +77,12 @@ class UserList extends RessourceList { } onClick(event) { + let userElement = event.target.closest('tr'); + if (userElement === null) {return;} + let userId = userElement.dataset.id; + if (userId === undefined) {return;} let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; - let userElement = event.target.closest('tr'); - let userId = userElement.dataset.id; switch (action) { case 'delete': { Utils.deleteUserRequest(userId); diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2 index b86d4cdb..d53dea34 100644 --- a/app/templates/_scripts.html.j2 +++ b/app/templates/_scripts.html.j2 @@ -1,5 +1,6 @@ + {%- assets filters='rjsmin', @@ -38,17 +39,19 @@ const currentUserId = {{ current_user.hashid|tojson }}; // Initialize components for current user - app.subscribeUser(currentUserId).catch((error) => {throw JSON.stringify(error);}); - app.getUser(currentUserId, true, true); + app.subscribeUser(currentUserId) + .catch((error) => {throw JSON.stringify(error);}); + app.getUser(currentUserId, true, true) + .catch((error) => {throw JSON.stringify(error);}); {%- endif %} // Disable all option elements with no value - for (let optionElementWithoutValue of document.querySelectorAll('option[value=""]')) { - optionElementWithoutValue.disabled = true; + for (let optionElement of document.querySelectorAll('option[value=""]')) { + optionElement.disabled = true; } - // Set the data-length attribute on inputs with the maxlength attribute - for (let inputElement of document.querySelectorAll('input[maxlength], textarea[maxlength]')) { + // Set the data-length attribute on textareas/inputs with the maxlength attribute + for (let inputElement of document.querySelectorAll('textarea[maxlength], input[maxlength]')) { inputElement.dataset.length = inputElement.getAttribute('maxlength'); } @@ -63,7 +66,7 @@ Form.autoInit(); // Display flashed messages - for (let flashedMessage of {{ get_flashed_messages(with_categories=True)|tojson }}) { - app.flash(flashedMessage[1], flashedMessage[0]); + for (let [category, message] of {{ get_flashed_messages(with_categories=True)|tojson }}) { + app.flash(message, message); } diff --git a/app/templates/_sidenav.html.j2 b/app/templates/_sidenav.html.j2 index ffdf86a6..965b50cc 100644 --- a/app/templates/_sidenav.html.j2 +++ b/app/templates/_sidenav.html.j2 @@ -24,13 +24,13 @@
  • new_labelContribute
  • Processes & Services
  • -
  • File setup
  • -
  • OCR
  • +
  • File setup
  • +
  • OCR
  • {% if config.NOPAQUE_TRANSKRIBUS_ENABLED %} -
  • HTR
  • +
  • HTR
  • {% endif %} -
  • NLP
  • -
  • Corpus analysis
  • +
  • NLP
  • +
  • Corpus analysis
  • Account
  • settingsGeneral Settings
  • diff --git a/app/templates/contributions/contributions.html.j2 b/app/templates/contributions/contributions.html.j2 index 4e513b9e..bdbcb10c 100644 --- a/app/templates/contributions/contributions.html.j2 +++ b/app/templates/contributions/contributions.html.j2 @@ -13,7 +13,7 @@
    - Tesseract OCR Pipeline Models + Tesseract OCR Pipeline Models

    Here you can see and edit the models that you have created. You can also create new models.

    @@ -23,7 +23,7 @@
    - SpaCy NLP Pipeline Models + SpaCy NLP Pipeline Models

    Here you can see and edit the models that you have created. You can also create new models.

    @@ -34,7 +34,7 @@
    - Transkribus HTR Pipeline Models + Transkribus HTR Pipeline Models

    Here you can see and edit the models that you have created. You can also create new models.

    diff --git a/app/templates/contributions/create_spacy_nlp_pipeline_model.html.j2 b/app/templates/contributions/create_spacy_nlp_pipeline_model.html.j2 index c1f452d3..e17ac9e5 100644 --- a/app/templates/contributions/create_spacy_nlp_pipeline_model.html.j2 +++ b/app/templates/contributions/create_spacy_nlp_pipeline_model.html.j2 @@ -16,7 +16,7 @@

     

     

    - + diff --git a/app/templates/contributions/create_tesseract_ocr_pipeline_model.html.j2 b/app/templates/contributions/create_tesseract_ocr_pipeline_model.html.j2 index e4c5a04b..ecede20a 100644 --- a/app/templates/contributions/create_tesseract_ocr_pipeline_model.html.j2 +++ b/app/templates/contributions/create_tesseract_ocr_pipeline_model.html.j2 @@ -16,7 +16,7 @@

     

     

    - + diff --git a/app/templates/corpora/analyse_corpus.html.j2 b/app/templates/corpora/analyse_corpus.html.j2 index 73ebfd77..69bcfd6e 100644 --- a/app/templates/corpora/analyse_corpus.html.j2 +++ b/app/templates/corpora/analyse_corpus.html.j2 @@ -4,7 +4,7 @@ {% block page_content %} diff --git a/app/templates/jobs/job.html.j2 b/app/templates/jobs/job.html.j2 index 5b78d055..c1222127 100644 --- a/app/templates/jobs/job.html.j2 +++ b/app/templates/jobs/job.html.j2 @@ -9,7 +9,7 @@
    -

    +

     

    diff --git a/app/templates/main/dashboard.html.j2 b/app/templates/main/dashboard.html.j2 index e296dd85..d6624f8a 100644 --- a/app/templates/main/dashboard.html.j2 +++ b/app/templates/main/dashboard.html.j2 @@ -82,7 +82,7 @@

    - +

    File setup

    @@ -94,7 +94,7 @@

    - +

    Optical Character Recognition

    @@ -106,7 +106,7 @@

    - +

    Natural Language Processing

    diff --git a/app/templates/main/dashboard2.html.j2 b/app/templates/main/dashboard2.html.j2 index c03834e3..d45aaa04 100644 --- a/app/templates/main/dashboard2.html.j2 +++ b/app/templates/main/dashboard2.html.j2 @@ -220,7 +220,7 @@

    - +

    File setup

    @@ -232,7 +232,7 @@

    - +

    Optical Character Recognition

    @@ -244,7 +244,7 @@

    - +

    Natural Language Processing

    diff --git a/app/templates/main/index.html.j2 b/app/templates/main/index.html.j2 index 5b450d61..74bfa306 100644 --- a/app/templates/main/index.html.j2 +++ b/app/templates/main/index.html.j2 @@ -77,7 +77,7 @@

     

    - +

    File setup

    @@ -86,7 +86,7 @@

     

    - +

    Optical Character Recognition

    @@ -95,7 +95,7 @@

     

    - +

    Transkribus HTR Pipeline

    @@ -104,7 +104,7 @@

     

    - +

    Natural Language Processing

    @@ -113,7 +113,7 @@

     

    - +

    Corpus analysis

    diff --git a/app/templates/services/corpus_analysis.html.j2 b/app/templates/services/corpus_analysis.html.j2 index e72d11b8..a7e3da8e 100644 --- a/app/templates/services/corpus_analysis.html.j2 +++ b/app/templates/services/corpus_analysis.html.j2 @@ -13,7 +13,7 @@ diff --git a/app/templates/services/file_setup_pipeline.html.j2 b/app/templates/services/file_setup_pipeline.html.j2 index eca9b8b7..ebc4cfc4 100644 --- a/app/templates/services/file_setup_pipeline.html.j2 +++ b/app/templates/services/file_setup_pipeline.html.j2 @@ -16,7 +16,7 @@

     

     

    - +
    diff --git a/app/templates/services/spacy_nlp_pipeline.html.j2 b/app/templates/services/spacy_nlp_pipeline.html.j2 index 6443c506..030ea163 100644 --- a/app/templates/services/spacy_nlp_pipeline.html.j2 +++ b/app/templates/services/spacy_nlp_pipeline.html.j2 @@ -16,7 +16,7 @@

     

     

    - +
    diff --git a/app/templates/services/tesseract_ocr_pipeline.html.j2 b/app/templates/services/tesseract_ocr_pipeline.html.j2 index c9617d5a..ff4fd38b 100644 --- a/app/templates/services/tesseract_ocr_pipeline.html.j2 +++ b/app/templates/services/tesseract_ocr_pipeline.html.j2 @@ -16,7 +16,7 @@

     

     

    - +
    diff --git a/app/templates/services/transkribus_htr_pipeline.html.j2 b/app/templates/services/transkribus_htr_pipeline.html.j2 index da14d53c..f5468ce9 100644 --- a/app/templates/services/transkribus_htr_pipeline.html.j2 +++ b/app/templates/services/transkribus_htr_pipeline.html.j2 @@ -16,7 +16,7 @@

     

     

    - +
    - delete - edit - send -
    + delete + edit + send +