diff --git a/app/routes.py b/app/routes.py index 9e4c974..d21d393 100644 --- a/app/routes.py +++ b/app/routes.py @@ -159,10 +159,13 @@ def iban(iban) -> str: {'key':'metatype', 'value': 'rule'} ) tag_rules = [r.get('name') for r in tag_rules if r.get('name')] + tag_rules.sort() + cat_rules = parent.db_handler.filter_metadata( {'key':'metatype', 'value': 'category'} ) cat_rules = [r.get('name') for r in cat_rules if r.get('name')] + cat_rules.sort() # All distinct Tags # (must be filtered on our own because TinyDB doesn't support 'distinct' queries) @@ -390,6 +393,25 @@ def getMeta(rule_filter): meta = parent.db_handler.filter_metadata(condition=None) return meta, 200 + @current_app.route('/api/deleteMeta/', methods=['DELETE'], defaults={'uuid':None}) + @current_app.route('/api/deleteMeta/', methods=['DELETE']) + def deleteMeta(uuid): + """ + Löschen von Metadaten anhand der ID + Args (uri): + uuid, str: ID der zu löschenden Metadaten + Returns: + json: Informationen zum Ergebnis der Löschaktion + """ + if not uuid: + return {'error': 'No ID provided'}, 400 + + r = parent.db_handler.delete_metadata(uuid) + if not r.get('deleted'): + return {'error': f'No data deleted: {r.get("error")}'}, 400 + + return r, 200 + @current_app.route('/api/upload/', methods=['POST']) def uploadIban(iban): """ diff --git a/app/static/js/functions.js b/app/static/js/functions.js index d5e37cf..5e2ddce 100644 --- a/app/static/js/functions.js +++ b/app/static/js/functions.js @@ -446,10 +446,13 @@ function apiGet(sub, params, callback, method = "GET") { * @param {string} sub - The API endpoint to append to the base URL. * @param {Object} params - An object containing key-value pairs to be sent as query parameters. * @param {function} callback - A callback function to handle the response. - * Receives the response text and status code as arguments. + * Receives the response text and status code as arguments. * @param {boolean} [isFile=false] - A switch to enable special file upload handling. + * @param {string} [force_method] - The HTTP method to use for the request (e.g., "POST", "PUT"). + * If not provided, it will be determined based on the presence of + * a file in the parameters. */ -function apiSubmit(sub, params, callback, isFile = false) { +function apiSubmit(sub, params, callback, isFile = false, force_method = undefined) { const ajax = createAjax(callback); let method; let request_uri; @@ -466,6 +469,11 @@ function apiSubmit(sub, params, callback, isFile = false) { request_uri = JSON.stringify(params); } + if (typeof force_method != "undefined") { + console.info("Setting method to", force_method.toUpperCase()) + method = force_method.toUpperCase(); + } + ajax.open(method, "/api/" + sub, true); if (method != "POST") { diff --git a/app/static/js/index.js b/app/static/js/index.js index f9b506f..2687e5a 100644 --- a/app/static/js/index.js +++ b/app/static/js/index.js @@ -190,13 +190,35 @@ function saveSetting() { showAjaxError(error, response); } else { - alert('Einstellungen gespeichert' + response) + alert('Einstellungen gespeichert (' + response.inserted + ')'); result_text.value = ''; } }, false); } +/** + * Delete a value from Metadate by uuid. + * The key is selected via the select input element 'read-setting'. + */ +function deleteSetting() { + const setting_uuid = document.getElementById('read-setting').value; + if (!setting_uuid) { + alert('Kein Name einer Einstellung angegeben!'); + return; + } + + apiSubmit('deleteMeta/' + setting_uuid, {}, function (response, error) { + if (error) { + showAjaxError(error, response); + + } else { + alert('Einstellung gelöscht !'); + window.location.reload(); + + } + }, false, 'DELETE'); +} // ---------------------------------------------------------------------------- // -- API Functions ----------------------------------------------------------- diff --git a/app/templates/index.html b/app/templates/index.html index 123ac79..e77dd8e 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -231,9 +231,13 @@

Settings

+

+ Settings ohne uuid werden als neuer Eintrag erstellt. +

diff --git a/handler/BaseDb.py b/handler/BaseDb.py index 1854d82..4b7f078 100644 --- a/handler/BaseDb.py +++ b/handler/BaseDb.py @@ -321,6 +321,17 @@ def set_metadata(self, entry: dict, overwrite: bool=True): """ raise NotImplementedError() + def delete_metadata(self, uuid: str): + """ + Löscht Metadaten aus der Datenbank. + + Args: + uuid (str): Unique ID (key) der zu löschenden Metadaten. + Returns: + dict: Informationen über den Löschvorgang. + """ + raise NotImplementedError() + def get_group_ibans(self, group: str, check_before: bool=False): """ Ruft die Liste von IBANs einer Gruppe aus der Datenbank ab. diff --git a/handler/MongoDb.py b/handler/MongoDb.py index 0f8e079..1148541 100644 --- a/handler/MongoDb.py +++ b/handler/MongoDb.py @@ -257,6 +257,11 @@ def set_metadata(self, entry, overwrite=True): return {'inserted': 0} + def delete_metadata(self, uuid): + collection = self.connection['metadata'] + delete_result = collection.delete_one({'uuid': uuid}) + return {'deleted': delete_result.deleted_count} + def _form_condition(self, condition): """ Erstellt aus einem Condition-Dict eine entsprechende Query @@ -300,7 +305,12 @@ def _form_condition(self, condition): if condition_method == 'all': stmt = {'$all': condition.get('value')} if condition_method == 'exact': - stmt = {'$all': condition.get('value'), '$size': len(condition.get('value'))} + if not condition.get('value'): + # Empty lists + stmt = {'$size': 0} + else: + # Lists with exact members + stmt = {'$all': condition.get('value')} # Nested or Plain Key condition_key = condition.get('key') diff --git a/handler/TinyDb.py b/handler/TinyDb.py index 1b50186..84be64d 100644 --- a/handler/TinyDb.py +++ b/handler/TinyDb.py @@ -310,6 +310,11 @@ def set_metadata(self, entry, overwrite=True): return {'inserted': 0} + def delete_metadata(self, uuid): + collection = self.connection.table('metadata') + deleted_ids = collection.remove(Query().uuid == uuid) + return {'deleted': len(deleted_ids)} + def _form_where(self, condition): """ Erstellt aus einem Condition-Dict eine entsprechende Query