From d412f2c61a26b3fe8322a40a7dc19b4b0f1aa68f Mon Sep 17 00:00:00 2001 From: Inga Kirschnick <inga.kirschnick@uni-bielefeld.de> Date: Thu, 17 Nov 2022 12:11:21 +0100 Subject: [PATCH] share toggle update in contributions --- app/contributions/routes.py | 18 ++++++ .../SpacyNLPPipelineModelList.js | 59 ++++++++++++++++--- .../TesseractOCRPipelineModelList.js | 59 ++++++++++++++++--- app/static/js/Utils.js | 46 +++++++++++++++ 4 files changed, 166 insertions(+), 16 deletions(-) diff --git a/app/contributions/routes.py b/app/contributions/routes.py index 79ed3fa8..67f1854c 100644 --- a/app/contributions/routes.py +++ b/app/contributions/routes.py @@ -134,6 +134,15 @@ def create_tesseract_ocr_pipeline_model(): title='Create Tesseract OCR Pipeline Model' ) +@bp.route('/tesseract-ocr-pipeline-models/<hashid:tesseract_ocr_pipeline_model_id>/toggle-public-status', methods=['POST']) +def share_tesseract_ocr_pipeline_model(tesseract_ocr_pipeline_model_id): + tesseract_ocr_pipeline_model = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id) + if not (tesseract_ocr_pipeline_model.user == current_user or current_user.is_administrator()): + abort(403) + tesseract_ocr_pipeline_model.shared = not tesseract_ocr_pipeline_model.shared + db.session.commit() + return {}, 201 + @bp.route('/spacy-nlp-pipeline-models') def spacy_nlp_pipeline_models(): @@ -239,3 +248,12 @@ def create_spacy_nlp_pipeline_model(): form=form, title='Create SpaCy NLP Pipeline Model' ) + +@bp.route('/spacy-nlp-pipeline-models/<hashid:spacy_nlp_pipeline_model_id>/toggle-public-status', methods=['POST']) +def share_spacy_nlp_pipeline_model(spacy_nlp_pipeline_model_id): + spacy_nlp_pipeline_model = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id) + if not (spacy_nlp_pipeline_model.user == current_user or current_user.is_administrator()): + abort(403) + spacy_nlp_pipeline_model.shared = not spacy_nlp_pipeline_model.shared + db.session.commit() + return {}, 201 diff --git a/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js b/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js index 9a760be0..2be53110 100644 --- a/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js +++ b/app/static/js/RessourceLists/SpacyNLPPipelineModelList.js @@ -16,9 +16,8 @@ class SpaCyNLPPipelineModelList extends RessourceList { <table> <thead> <tr> - <th>Title</th> - <th>Description</th> - <th>Biblio</th> + <th>Title and Description</th> + <th>Publisher</th> <th></th> </tr> </thead> @@ -29,9 +28,18 @@ class SpaCyNLPPipelineModelList extends RessourceList { }, item: ` <tr class="clickable hoverable"> - <td><span class="title"></span></td> - <td><span class="description"></span></td> - <td><a class="publisher-url"><span class="publisher"></span></a> (<span class="publishing-year"></span>), <span class="title-2"></span> <span class="version"></span>, <a class="publishing-url"><span class="publishing-url-2"></span></a></td> + <td><b><span class="title"></span> <span class="version"></span></b><br><i><span class="description"></span></i></td> + <td><a class="publisher-url"><span class="publisher"></span></a> (<span class="publishing-year"></span>)<br><a class="publishing-url"><span class="publishing-url-2"></span></a></td> + <td> + <div class="switch action-switch center-align" data-action="share-request"> + <span class="share"></span> + <label> + <input type="checkbox" class="shared"> + <span class="lever"></span> + shared + </label> + </div> + </td> <td class="right-align"> <a class="action-button btn-floating red waves-effect waves-light" data-action="delete-request"><i class="material-icons">delete</i></a> <a class="action-button btn-floating service-color darken waves-effect waves-light service-2" data-action="view"><i class="material-icons">send</i></a> @@ -50,7 +58,8 @@ class SpaCyNLPPipelineModelList extends RessourceList { 'publishing-year': spaCyNLPPipelineModel.publishing_year, 'title': spaCyNLPPipelineModel.title, 'title-2': spaCyNLPPipelineModel.title, - 'version': spaCyNLPPipelineModel.version + 'version': spaCyNLPPipelineModel.version, + 'shared': spaCyNLPPipelineModel.shared ? 'True' : 'False' }; }, sortArgs: ['creation-date', {order: 'desc'}], @@ -65,19 +74,31 @@ class SpaCyNLPPipelineModelList extends RessourceList { 'publishing-year', 'title', 'title-2', - 'version' + 'version', + {name: 'shared', attr: 'data-checked'} ] }; constructor(listElement, options = {}) { super(listElement, {...SpaCyNLPPipelineModelList.options, ...options}); + this.listjs.list.addEventListener('change', (event) => {this.onChange(event)}); } init (user) { this._init(user.spacy_nlp_pipeline_models); } + _init(ressources) { + super._init(ressources); + for (let uncheckedCheckbox of this.listjs.list.querySelectorAll('input[data-checked="True"]')) { + uncheckedCheckbox.setAttribute('checked', ''); + } + } + onClick(event) { + if (event.target.closest('.action-switch')) { + return; + } let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; let spaCyNLPPipelineModelElement = event.target.closest('tr'); @@ -96,4 +117,26 @@ class SpaCyNLPPipelineModelList extends RessourceList { } } } + + onChange(event) { + let actionSwitchElement = event.target.closest('.action-switch'); + let action = actionSwitchElement.dataset.action; + let spaCyNLPPipelineModelElement = event.target.closest('tr'); + let spaCyNLPPipelineModelId = spaCyNLPPipelineModelElement.dataset.id; + switch (action) { + case 'share-request': { + let shared; + if (actionSwitchElement.querySelector('input').checked) { + shared = true; + } else { + shared = false; + } + Utils.shareSpaCyNLPPipelineModelRequest(this.userId, spaCyNLPPipelineModelId, shared); + break; + } + default: { + break; + } + } + } } diff --git a/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js b/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js index 36dea105..8a987016 100644 --- a/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js +++ b/app/static/js/RessourceLists/TesseractOCRPipelineModelList.js @@ -16,9 +16,8 @@ class TesseractOCRPipelineModelList extends RessourceList { <table> <thead> <tr> - <th>Title</th> - <th>Description</th> - <th>Biblio</th> + <th>Title and Description</th> + <th>Publisher</th> <th></th> </tr> </thead> @@ -29,9 +28,18 @@ class TesseractOCRPipelineModelList extends RessourceList { }, item: ` <tr class="clickable hoverable"> - <td><span class="title"></span></td> - <td><span class="description"></span></td> - <td><a class="publisher-url"><span class="publisher"></span></a> (<span class="publishing-year"></span>), <span class="title-2"></span> <span class="version"></span>, <a class="publishing-url"><span class="publishing-url-2"></span></a></td> + <td><b><span class="title"></span> <span class="version"></span></b><br><i><span class="description"></span></i></td> + <td><a class="publisher-url"><span class="publisher"></span></a> (<span class="publishing-year"></span>)<br><a class="publishing-url"><span class="publishing-url-2"></span></a></td> + <td> + <div class="switch action-switch center-align" data-action="share-request"> + <span class="share"></span> + <label> + <input type="checkbox" class="shared"> + <span class="lever"></span> + shared + </label> + </div> + </td> <td class="right-align"> <a class="action-button btn-floating red waves-effect waves-light" data-action="delete-request"><i class="material-icons">delete</i></a> <a class="action-button btn-floating service-color darken waves-effect waves-light service-2" data-action="view"><i class="material-icons">send</i></a> @@ -50,7 +58,8 @@ class TesseractOCRPipelineModelList extends RessourceList { 'publishing-year': tesseractOCRPipelineModel.publishing_year, 'title': tesseractOCRPipelineModel.title, 'title-2': tesseractOCRPipelineModel.title, - 'version': tesseractOCRPipelineModel.version + 'version': tesseractOCRPipelineModel.version, + 'shared': tesseractOCRPipelineModel.shared ? 'True' : 'False' }; }, sortArgs: ['creation-date', {order: 'desc'}], @@ -65,19 +74,31 @@ class TesseractOCRPipelineModelList extends RessourceList { 'publishing-year', 'title', 'title-2', - 'version' + 'version', + {name: 'shared', attr: 'data-checked'} ] }; constructor(listElement, options = {}) { super(listElement, {...TesseractOCRPipelineModelList.options, ...options}); + this.listjs.list.addEventListener('change', (event) => {this.onChange(event)}); } init (user) { this._init(user.tesseract_ocr_pipeline_models); } + _init(ressources) { + super._init(ressources); + for (let uncheckedCheckbox of this.listjs.list.querySelectorAll('input[data-checked="True"]')) { + uncheckedCheckbox.setAttribute('checked', ''); + } + } + onClick(event) { + if (event.target.closest('.action-switch')) { + return; + } let actionButtonElement = event.target.closest('.action-button'); let action = actionButtonElement === null ? 'view' : actionButtonElement.dataset.action; let tesseractOCRPipelineModelElement = event.target.closest('tr'); @@ -96,4 +117,26 @@ class TesseractOCRPipelineModelList extends RessourceList { } } } + + onChange(event) { + let actionSwitchElement = event.target.closest('.action-switch'); + let action = actionSwitchElement.dataset.action; + let tesseractOCRPipelineModelElement = event.target.closest('tr'); + let tesseractOCRPipelineModelId = tesseractOCRPipelineModelElement.dataset.id; + switch (action) { + case 'share-request': { + let shared; + if (actionSwitchElement.querySelector('input').checked) { + shared = true; + } else { + shared = false; + } + Utils.shareTesseractOCRPipelineModelRequest(this.userId, tesseractOCRPipelineModelId, shared); + break; + } + default: { + break; + } + } + } } diff --git a/app/static/js/Utils.js b/app/static/js/Utils.js index 4a274054..6de95033 100644 --- a/app/static/js/Utils.js +++ b/app/static/js/Utils.js @@ -419,4 +419,50 @@ class Utils { modal.open(); }); } + + static shareTesseractOCRPipelineModelRequest(userId, tesseractOCRPipelineModelId, shared) { + return new Promise((resolve, reject) => { + let tesseractOCRPipelineModel = app.data.users[userId].tesseract_ocr_pipeline_models[tesseractOCRPipelineModelId]; + let msg = ''; + if (shared) { + msg = `Model "${tesseractOCRPipelineModel.title}" is now public`; + } else { + msg = `Model "${tesseractOCRPipelineModel.title}" is now private`; + } + fetch(`/contributions/spacy-nlp-pipeline-models/${tesseractOCRPipelineModel.id}/toggle-public-status`, {method: 'POST', headers: {Accept: 'application/json'}}) + .then( + (response) => { + app.flash(msg, 'corpus'); + resolve(response); + }, + (response) => { + if (response.status === 403) {app.flash('Forbidden', 'error');} + reject(response); + } + ); + }); + } + + static shareSpaCyNLPPipelineModelRequest(userId, spaCyNLPPipelineModelId, shared) { + return new Promise((resolve, reject) => { + let spaCyNLPPipelineModel = app.data.users[userId].spacy_nlp_pipeline_models[spaCyNLPPipelineModelId]; + let msg = ''; + if (shared) { + msg = `Model "${spaCyNLPPipelineModel.title}" is now public`; + } else { + msg = `Model "${spaCyNLPPipelineModel.title}" is now private`; + } + fetch(`/contributions/spacy-nlp-pipeline-models/${spaCyNLPPipelineModel.id}/toggle-public-status`, {method: 'POST', headers: {Accept: 'application/json'}}) + .then( + (response) => { + app.flash(msg, 'corpus'); + resolve(response); + }, + (response) => { + if (response.status === 403) {app.flash('Forbidden', 'error');} + reject(response); + } + ); + }); + } } -- GitLab