From cf69427e87b4acff6185563d4efc3e58d63788fd Mon Sep 17 00:00:00 2001 From: CasVT Date: Thu, 8 Jun 2023 14:34:02 +0200 Subject: [PATCH] Added search to static reminders and templates --- backend/reminders.py | 1 - backend/static_reminders.py | 22 ++++++- backend/templates.py | 20 ++++++ frontend/api.py | 46 ++++++++++++++ frontend/static/css/library.css | 6 +- frontend/static/js/general.js | 6 +- frontend/static/js/library.js | 31 +++++++-- frontend/templates/reminders.html | 102 ++++++++++++++---------------- 8 files changed, 167 insertions(+), 67 deletions(-) diff --git a/backend/reminders.py b/backend/reminders.py index 7724f17..9827289 100644 --- a/backend/reminders.py +++ b/backend/reminders.py @@ -17,7 +17,6 @@ from backend.db import close_db, get_db filter_function = lambda query, p: ( query in p["title"].lower() or query in p["text"].lower() - or query in p["notification_service_title"].lower() ) def _find_next_time( diff --git a/backend/static_reminders.py b/backend/static_reminders.py index 8801882..a3a0ba1 100644 --- a/backend/static_reminders.py +++ b/backend/static_reminders.py @@ -9,6 +9,10 @@ from backend.custom_exceptions import (NotificationServiceNotFound, ReminderNotFound) from backend.db import get_db +filter_function = lambda query, p: ( + query in p["title"].lower() + or query in p["text"].lower() +) class StaticReminder: """Represents a static reminder @@ -147,7 +151,23 @@ class StaticReminders: )) return reminders - + + def search(self, query: str) -> List[dict]: + """Search for static reminders + + Args: + query (str): The term to search for + + Returns: + List[dict]: All static reminders that match. Similar output to self.fetchall + """ + query = query.lower() + reminders = list(filter( + lambda p: filter_function(query, p), + self.fetchall() + )) + return reminders + def fetchone(self, id: int) -> StaticReminder: """Get one static reminder diff --git a/backend/templates.py b/backend/templates.py index 9343c8d..bc5f65f 100644 --- a/backend/templates.py +++ b/backend/templates.py @@ -7,6 +7,10 @@ from backend.custom_exceptions import (NotificationServiceNotFound, TemplateNotFound) from backend.db import get_db +filter_function = lambda query, p: ( + query in p["title"].lower() + or query in p["text"].lower() +) class Template: """Represents a template @@ -136,6 +140,22 @@ class Templates: return templates + def search(self, query: str) -> List[dict]: + """Search for templates + + Args: + query (str): The term to search for + + Returns: + List[dict]: All templates that match. Similar output to self.fetchall + """ + query = query.lower() + reminders = list(filter( + lambda p: filter_function(query, p), + self.fetchall() + )) + return reminders + def fetchone(self, id: int) -> Template: """Get one template diff --git a/frontend/api.py b/frontend/api.py index 48bc0ea..ae19fcf 100644 --- a/frontend/api.py +++ b/frontend/api.py @@ -632,6 +632,29 @@ def api_get_templates(): color=color) return return_api(result.get(), code=201) +@api.route('/templates/search', methods=['GET']) +@error_handler +@auth +def api_templates_query(): + """ + Endpoint: /templates/search + Description: Search through the list of templates + Requires being logged in: Yes + Methods: + GET: + Parameters (url): + query (required): The search term + Returns: + 200: + The search results, listed like GET /templates + 400: + KeyNotFound: One of the required parameters was not given + """ + query = extract_key(request.values, 'query') + + result = g.user_data.templates.search(query) + return return_api(result) + @api.route('/templates/', methods=['GET', 'PUT', 'DELETE']) @error_handler @auth @@ -746,6 +769,29 @@ def api_static_reminders_list(): color=color) return return_api(result.get(), code=201) +@api.route('/staticreminders/search', methods=['GET']) +@error_handler +@auth +def api_static_reminders_query(): + """ + Endpoint: /staticreminders/search + Description: Search through the list of staticreminders + Requires being logged in: Yes + Methods: + GET: + Parameters (url): + query (required): The search term + Returns: + 200: + The search results, listed like GET /staticreminders + 400: + KeyNotFound: One of the required parameters was not given + """ + query = extract_key(request.values, 'query') + + result = g.user_data.static_reminders.search(query) + return return_api(result) + @api.route('/staticreminders/', methods=['GET', 'POST', 'PUT', 'DELETE']) @error_handler @auth diff --git a/frontend/static/css/library.css b/frontend/static/css/library.css index 80562e9..2b2e6ba 100644 --- a/frontend/static/css/library.css +++ b/frontend/static/css/library.css @@ -46,9 +46,9 @@ } /* REMINDER LIST */ -#reminder-list, -#static-reminder-list, -#template-list { +#reminder-tab, +#static-reminder-tab, +#template-tab { --gap: 1rem; --entry-width: 13rem; max-width: 43rem; diff --git a/frontend/static/js/general.js b/frontend/static/js/general.js index 32ffd2e..85b8069 100644 --- a/frontend/static/js/general.js +++ b/frontend/static/js/general.js @@ -1,7 +1,7 @@ const types = { - 'reminder': document.getElementById('reminder-list'), - 'static_reminder': document.getElementById('static-reminder-list'), - 'template': document.getElementById('template-list') + 'reminder': document.getElementById('reminder-tab'), + 'static_reminder': document.getElementById('static-reminder-tab'), + 'template': document.getElementById('template-tab') }; const icons = { diff --git a/frontend/static/js/library.js b/frontend/static/js/library.js index 3f9d990..47ada58 100644 --- a/frontend/static/js/library.js +++ b/frontend/static/js/library.js @@ -5,7 +5,7 @@ function showTab(button) { ); // Show desired tab and hide all others - document.querySelectorAll('#home > div:not(.tab-selector)').forEach( + document.querySelectorAll('#home > div:not(.tab-selector):not(.search-container)').forEach( e => e.classList.add('hidden') ); document.getElementById(button.dataset.target).classList.remove('hidden'); @@ -87,13 +87,25 @@ function fillTemplates() { // Library search // function searchLibrary() { - const query = document.querySelector('#search-input').value; - fetch(`${url_prefix}/api/reminders/search?api_key=${api_key}&query=${query}`) + const query = document.querySelector('#search-input').value, + tab = document.getElementById( + document.querySelector('.tab-selector > button[data-selected="true"]').dataset.target + ) + let url; + if (tab === types.reminder) + url = `${url_prefix}/api/reminders/search?api_key=${api_key}&query=${query}`; + else if (tab === types.static_reminder) + url = `${url_prefix}/api/staticreminders/search?api_key=${api_key}&query=${query}`; + else if (tab === types.template) + url = `${url_prefix}/api/templates/search?api_key=${api_key}&query=${query}`; + else return; + + fetch(url) .then(response => { if (!response.ok) return Promise.reject(response.status); return response.json(); }) - .then(json => fillTable(types.reminder, json.result)) + .then(json => fillTable(tab, json.result)) .catch(e => { if (e === 401) window.location.href = `${url_prefix}/`; @@ -104,7 +116,16 @@ function searchLibrary() { function clearSearchLibrary() { document.querySelector('#search-input').value = ''; - fillReminders(); + const tab = document.getElementById( + document.querySelector('.tab-selector > button[data-selected="true"]').dataset.target + ) + if (tab === types.reminder) + fillReminders(); + else if (tab === types.static_reminder) + fillStaticReminders(); + else if (tab === types.template) + fillTemplates(); + else return; }; // code run on load diff --git a/frontend/templates/reminders.html b/frontend/templates/reminders.html index 2050993..57e26f2 100644 --- a/frontend/templates/reminders.html +++ b/frontend/templates/reminders.html @@ -81,71 +81,65 @@ -
-
- -
- -
-
-
- + + +
+ +
+
+ -
+ + +

Add a notification service first!

+