From 872788148ec01ae09491ceb76e93351983aca648 Mon Sep 17 00:00:00 2001 From: TreyWW <73353716+TreyWW@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:13:42 +0000 Subject: [PATCH 1/5] added basic dropdown content --- backend/core/api/base/global_search.py | 67 ++++++++++ backend/core/api/base/urls.py | 7 +- .../base/topbar/_search_dropdown.html | 66 ++++++++++ frontend/templates/base/topbar/_topbar.html | 118 ++++++++++-------- 4 files changed, 202 insertions(+), 56 deletions(-) create mode 100644 backend/core/api/base/global_search.py create mode 100644 frontend/templates/base/topbar/_search_dropdown.html diff --git a/backend/core/api/base/global_search.py b/backend/core/api/base/global_search.py new file mode 100644 index 000000000..d7a4ec7a8 --- /dev/null +++ b/backend/core/api/base/global_search.py @@ -0,0 +1,67 @@ +from django.shortcuts import render +from django.urls import reverse + +from backend.core.types.requests import WebRequest + + +def global_search_endpoint(request: WebRequest): + services = { + "invoices": { + "description": "Simplify your billing for customers", + "icon": "fa-file-invoice", + "url": reverse("finance:invoices:single:dashboard"), + "features": { + "Single": reverse("finance:invoices:single:dashboard"), + "Recurring": reverse("finance:invoices:recurring:dashboard") + } + }, + "clients": { + "description": "Simplified customer information storage", + "icon": "fa-users", + "url": reverse("clients:dashboard"), + "features": { + "View All": reverse("clients:dashboard"), + "Create new customer": reverse("clients:create") + } + } + } + + resources = { + "invoice": [ + { + "name": "#23", + "details": { + "Due Date": "12/11/2024", + "Total Amount": "£1,333" + } + }, + { + "name": "#24", + "details": { + "Due Date": "23/11/2024", + "Total Amount": "£433.20" + } + } + ], + "client": [ + { + "name": "Bob Smith (#21)", + "details": { + } + }, + { + "name": "Jeff Smith (#22)", + "details": { + } + } + ] + } + + return render( + request, "base/topbar/_search_dropdown.html", { + "services": services, + "resources": resources, + "resource_count": sum(len(v) for v in resources.values()), + "search": request.GET.get("search") + } + ) diff --git a/backend/core/api/base/urls.py b/backend/core/api/base/urls.py index 539b0c64d..1bbd57f8a 100644 --- a/backend/core/api/base/urls.py +++ b/backend/core/api/base/urls.py @@ -1,5 +1,5 @@ from django.urls import path -from . import modal, notifications, breadcrumbs +from . import modal, notifications, breadcrumbs, global_search urlpatterns = [ path( @@ -24,6 +24,11 @@ name="notifications delete", ), path("breadcrumbs/refetch/", breadcrumbs.update_breadcrumbs_endpoint, name="breadcrumbs refetch"), + path( + "global_search", + global_search.global_search_endpoint, + name="global_search" + ) ] app_name = "base" diff --git a/frontend/templates/base/topbar/_search_dropdown.html b/frontend/templates/base/topbar/_search_dropdown.html new file mode 100644 index 000000000..faeb6c471 --- /dev/null +++ b/frontend/templates/base/topbar/_search_dropdown.html @@ -0,0 +1,66 @@ +
+
Results for {{ search }}
+ {% if services %} +
+ Services ({{ services | length }}) +
+
+
+ {% for service_name, service in services.items %} +
+
+ +
+
+ {{ service_name | title }} +
{{ service.description }}
+
+
+ Features +
+ {% for feature_name, url in service.features.items %} + {{ feature_name }} + {% endfor %} +
+
+
+
+ {% endfor %} +
+ {% endif %} + {% if resource_count %} +
+ Resources ({{ resource_count }}) +
+
+
+ {% for resource_type, resource_list in resources.items %} + {% for resource in resource_list %} +
+
+ +
+
+ {{ resource.name }} +
{{ resource_type | title }}
+
+
+
+ {% for detail_name, resource_detail in resource.details.items %} +
+
+ {{ detail_name }}: {{ resource_detail }} +
+ {% endfor %} +
+
+
+
+ {% endfor %} + {% endfor %} +
+ {% endif %} +
diff --git a/frontend/templates/base/topbar/_topbar.html b/frontend/templates/base/topbar/_topbar.html index c387696e6..8be142ab5 100644 --- a/frontend/templates/base/topbar/_topbar.html +++ b/frontend/templates/base/topbar/_topbar.html @@ -64,62 +64,70 @@ {% if feature_enabled_invoices %}
  • - + Invoices + +
  • + {% endif %} +
    +
  • + - Invoices - -
  • - {% endif %} -
    -
  • - Clients - -
  • - {% if feature_enabled_monthly_reports %} -
    -
  • - - - Monthly Reports - -
  • - {% endif %} - - - + From f0c7d141a4446374a7a4c0bb2ae39cdfdd4e75cf Mon Sep 17 00:00:00 2001 From: TreyWW <73353716+TreyWW@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:21:34 +0000 Subject: [PATCH 2/5] added random colour and URL --- backend/core/api/base/global_search.py | 1 + frontend/templates/base/topbar/_search_dropdown.html | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/core/api/base/global_search.py b/backend/core/api/base/global_search.py index d7a4ec7a8..b7b51f2d7 100644 --- a/backend/core/api/base/global_search.py +++ b/backend/core/api/base/global_search.py @@ -30,6 +30,7 @@ def global_search_endpoint(request: WebRequest): "invoice": [ { "name": "#23", + "url": reverse("finance:invoices:single:overview", args=["23"]), "details": { "Due Date": "12/11/2024", "Total Amount": "£1,333" diff --git a/frontend/templates/base/topbar/_search_dropdown.html b/frontend/templates/base/topbar/_search_dropdown.html index faeb6c471..614e2ec98 100644 --- a/frontend/templates/base/topbar/_search_dropdown.html +++ b/frontend/templates/base/topbar/_search_dropdown.html @@ -1,3 +1,4 @@ +{% load to_list from strfilters %}
    Results for {{ search }}
    {% if services %} @@ -31,7 +32,7 @@
    {% endif %} {% if resource_count %} -
    +
    Resources ({{ resource_count }})

    @@ -44,14 +45,17 @@
    - {{ resource.name }} + {{ resource.name }}
    {{ resource_type | title }}

    {% for detail_name, resource_detail in resource.details.items %}
    -
    + {% with rc='bg-primary,bg-secondary,bg-error,bg-info'|to_list|random %} +
    + {% endwith %} {{ detail_name }}: {{ resource_detail }}
    {% endfor %} From 75f7aa6a09e147901fe0e4910cc6eead5e63fbe5 Mon Sep 17 00:00:00 2001 From: misoed <113443870+misoed@users.noreply.github.com> Date: Tue, 26 Nov 2024 19:28:00 +0100 Subject: [PATCH 3/5] Update global_search.py implementation of global search --- backend/core/api/base/global_search.py | 254 ++++++++++++++++++++----- 1 file changed, 209 insertions(+), 45 deletions(-) diff --git a/backend/core/api/base/global_search.py b/backend/core/api/base/global_search.py index b7b51f2d7..508f5716c 100644 --- a/backend/core/api/base/global_search.py +++ b/backend/core/api/base/global_search.py @@ -1,68 +1,232 @@ from django.shortcuts import render -from django.urls import reverse -from backend.core.types.requests import WebRequest +from backend.core.models import User, TeamMemberPermission +from backend.models import Client, Invoice -def global_search_endpoint(request: WebRequest): +def global_search_endpoint(request): + search_text = request.GET.get("search", "").strip().lower() + + # Mapping for pages + page_mappings = { + "dashboard": "/dashboard/", + "receipts": "/dashboard/receipts/", + "invoices single": "/dashboard/invoices/single/", + "invoices recurring": "/dashboard/invoices/recurring/", + "clients": "/dashboard/clients/", + "file storage": "/dashboard/file_storage/", + "settings": "/dashboard/settings/", + "api keys": "/dashboard/settings/api_keys/", + } + + # Available services services = { + "dashboard": { + "description": "Access your main dashboard", + "icon": "fa-home", + "url": page_mappings["dashboard"], + }, "invoices": { "description": "Simplify your billing for customers", "icon": "fa-file-invoice", - "url": reverse("finance:invoices:single:dashboard"), + "url": page_mappings["invoices single"], "features": { - "Single": reverse("finance:invoices:single:dashboard"), - "Recurring": reverse("finance:invoices:recurring:dashboard") - } + "Single": page_mappings["invoices single"], + "Recurring": page_mappings["invoices recurring"], + }, }, "clients": { "description": "Simplified customer information storage", "icon": "fa-users", - "url": reverse("clients:dashboard"), + "url": page_mappings["clients"], + "features": { + "View All": page_mappings["clients"], + "Create new customer": f"{page_mappings['clients']}create/", + }, + }, + "file storage": { + "description": "Manage your files securely", + "icon": "fa-folder", + "url": page_mappings["file storage"], + }, + "receipts": { + "description": "Access your receipts", + "icon": "fa-receipt", + "url": page_mappings["receipts"], + }, + "settings": { + "description": "Configure system settings", + "icon": "fa-cogs", + "url": page_mappings["settings"], "features": { - "View All": reverse("clients:dashboard"), - "Create new customer": reverse("clients:create") - } - } + "API Keys": page_mappings["api keys"], + }, + }, } + # Filter services based on search text + filtered_services = {} + for key, value in services.items(): + # Check if search_text matches service name + if search_text in key.lower(): + filtered_services[key] = value + continue + + # Check if search_text matches any feature name + if "features" in value: + for feature_name in value["features"]: + if search_text in feature_name.lower(): + filtered_services[key] = value + break + resources = { - "invoice": [ - { - "name": "#23", - "url": reverse("finance:invoices:single:overview", args=["23"]), - "details": { - "Due Date": "12/11/2024", - "Total Amount": "£1,333" - } - }, - { - "name": "#24", - "details": { - "Due Date": "23/11/2024", - "Total Amount": "£433.20" - } - } - ], - "client": [ - { - "name": "Bob Smith (#21)", - "details": { - } - }, - { - "name": "Jeff Smith (#22)", - "details": { - } - } - ] + "invoice": [], + "client": [], } + # Fetch only permitted clients + def get_permitted_clients(request): + if isinstance(request.actor, User): + return Client.objects.filter(user=request.user) + elif ( + request.team.is_owner(request.user) + or "clients:read" in TeamMemberPermission.objects.filter(team=request.team, user=request.user).first().scopes + ): + return Client.objects.filter(organization=request.team) + else: + return Client.objects.none() + + # Fetch only permitted invoices + def get_permitted_invoices(request): + if isinstance(request.actor, User): + return Invoice.objects.filter(user=request.user) + elif ( + request.team.is_owner(request.user) + or "clients:read" in TeamMemberPermission.objects.filter(team=request.team, user=request.user).first().scopes + ): + return Invoice.objects.filter(organization=request.team) + else: + return Invoice.objects.none() + + # Fetch resources only if search_text is present + if search_text: + # Track added IDs to avoid duplicates (duplicates appeared when I searched for exact client or Invoice) + added_invoice_ids = set() + added_client_ids = set() + + matched_filter = None # To allow invoices to be searched by multiple queries + # Fetch exact matches for Clients + permitted_clients = get_permitted_clients(request) + exact_client = permitted_clients.filter(name__iexact=search_text).first() + if exact_client: + resources["client"].append( + { + "name": f"{exact_client.name} (#{exact_client.id})", + "url": f"{page_mappings['clients']}{exact_client.id}/", + "details": { + "Phone Number": f"{exact_client.phone_number}" if exact_client.phone_number else "N/A", + "Email": f"{exact_client.email}" if exact_client.email else "N/A", + }, + } + ) + added_client_ids.add(exact_client.id) # To avoid duplicates + + # Fetch partial matches for Clients + partial_clients = permitted_clients.filter(name__icontains=search_text) + for client in partial_clients: + if client.id not in added_client_ids: # If current ID is not in already found ID's + resources["client"].append( + { + "name": f"{client.name} (#{client.id})", + "url": f"{page_mappings['clients']}{client.id}/", + "details": { + "Phone Number": f"{client.phone_number}" if client.phone_number else "N/A", + "Email": f"{client.email}" if client.email else "N/A", + }, + } + ) + added_client_ids.add(client.id) # To avoid duplicates + + # Save permitted invoices to variable + permitted_invoices = get_permitted_invoices(request) + + if search_text.isdigit(): + # Fetch by ID if it's valid ID + exact_invoice = permitted_invoices.filter(id=int(search_text)).first() + if exact_invoice: + resources["invoice"].append( + { + "name": f"{exact_invoice.client_company} (#{exact_invoice.id})", + "url": f"{page_mappings['invoices single']}{exact_invoice.id}", + "details": { + "Due Date": exact_invoice.date_due.strftime("%d/%m/%Y") if exact_invoice.date_due else "N/A", + "Total Amount": ( + f"{exact_invoice.get_total_price()} {exact_invoice.currency}" if exact_invoice.get_total_price() else "N/A" + ), + "Client Name": exact_invoice.client_name, + }, + } + ) + + else: + # Fetch exact matches for Invoices + exact_invoice = permitted_invoices.filter(client_name__iexact=search_text) + if exact_invoice: + matched_filter = "client_name" # Save used filter + else: + # If no match for client_name, try client_company + exact_invoice = permitted_invoices.filter(client_company__iexact=search_text) + if exact_invoice: + matched_filter = "client_company" + for invoice in exact_invoice: + resources["invoice"].append( + { + "name": f"{invoice.client_name if matched_filter == 'client_name' else invoice.client_company} (#{invoice.id})", + "url": f"{page_mappings['invoices single']}{invoice.id}", + "details": { + "Due Date": invoice.date_due.strftime("%d/%m/%Y") if invoice.date_due else "N/A", + "Total Amount": f"{invoice.get_total_price()} {invoice.currency}" if invoice.get_total_price() else "N/A", + "Company" if matched_filter == "client_name" else "Client": ( + invoice.client_company if matched_filter == "client_name" else invoice.client_name + ), + }, + } + ) + added_invoice_ids.add(invoice.id) # To avoid duplicates + + # Fetch partial matches for Invoices + partial_invoices = permitted_invoices.filter(client_name__icontains=search_text) + if partial_invoices: + matched_filter = "client_name" # Save used filter + else: + # If no match for client_name, try client_company + partial_invoices = permitted_invoices.filter(client_company__icontains=search_text) + if partial_invoices: + matched_filter = "client_company" + for invoice in partial_invoices: + if invoice.id not in added_invoice_ids: # If current ID is not in already found ID's + resources["invoice"].append( + { + "name": f"{invoice.client_name if matched_filter == 'client_name' else invoice.client_company} (#{invoice.id})", + "url": f"{page_mappings['invoices single']}{invoice.id}", + "details": { + "Due Date": invoice.date_due.strftime("%d/%m/%Y") if invoice.date_due else "N/A", + "Total Amount": f"{invoice.get_total_price()} {invoice.currency}" if invoice.get_total_price() else "N/A", + "Company" if matched_filter == "client_name" else "Client": ( + invoice.client_company if matched_filter == "client_name" else invoice.client_name + ), + }, + } + ) + added_invoice_ids.add(invoice.id) # To avoid duplicates + return render( - request, "base/topbar/_search_dropdown.html", { - "services": services, + request, + "base/topbar/_search_dropdown.html", + { + "services": filtered_services, "resources": resources, "resource_count": sum(len(v) for v in resources.values()), - "search": request.GET.get("search") - } + "search": search_text, + }, ) From 48c24dad827d94ef7f58eee9a53169a20a713fc6 Mon Sep 17 00:00:00 2001 From: Trey <73353716+TreyWW@users.noreply.github.com> Date: Tue, 26 Nov 2024 21:21:59 +0000 Subject: [PATCH 4/5] minor changes to improve design and some backend cleanliness Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com> --- backend/core/api/base/global_search.py | 186 ++++++++++-------- .../base/topbar/_search_dropdown.html | 40 ++-- frontend/templates/base/topbar/_topbar.html | 138 +++++++------ 3 files changed, 199 insertions(+), 165 deletions(-) diff --git a/backend/core/api/base/global_search.py b/backend/core/api/base/global_search.py index 508f5716c..721928d0b 100644 --- a/backend/core/api/base/global_search.py +++ b/backend/core/api/base/global_search.py @@ -109,116 +109,138 @@ def get_permitted_invoices(request): return Invoice.objects.none() # Fetch resources only if search_text is present - if search_text: - # Track added IDs to avoid duplicates (duplicates appeared when I searched for exact client or Invoice) - added_invoice_ids = set() - added_client_ids = set() - - matched_filter = None # To allow invoices to be searched by multiple queries - # Fetch exact matches for Clients - permitted_clients = get_permitted_clients(request) - exact_client = permitted_clients.filter(name__iexact=search_text).first() - if exact_client: + + if not search_text: + return render( + request, + "base/topbar/_search_dropdown.html", + { + "services": filtered_services, + }, + ) + + # Track added IDs to avoid duplicates (duplicates appeared when I searched for exact client or Invoice) + added_invoice_ids = set() + added_client_ids = set() + + matched_filter = None # To allow invoices to be searched by multiple queries + + # Fetch exact matches for Clients + permitted_clients = get_permitted_clients(request) + exact_client = permitted_clients.filter(name__iexact=search_text).first() + if exact_client: + resources["client"].append( + { + "name": f"{exact_client.name} (#{exact_client.id})", + "url": f"{page_mappings['clients']}{exact_client.id}/", + "details": { + "Phone Number": f"{exact_client.phone_number}" if exact_client.phone_number else "N/A", + "Email": f"{exact_client.email}" if exact_client.email else "N/A", + }, + } + ) + added_client_ids.add(exact_client.id) # To avoid duplicates + + # Fetch partial matches for Clients + partial_clients = permitted_clients.filter(name__icontains=search_text) + for client in partial_clients: + if client.id not in added_client_ids: # If current ID is not in already found ID's resources["client"].append( { - "name": f"{exact_client.name} (#{exact_client.id})", - "url": f"{page_mappings['clients']}{exact_client.id}/", + "name": f"{client.name} (#{client.id})", + "url": f"{page_mappings['clients']}{client.id}/", "details": { - "Phone Number": f"{exact_client.phone_number}" if exact_client.phone_number else "N/A", - "Email": f"{exact_client.email}" if exact_client.email else "N/A", + "Phone Number": f"{client.phone_number}" if client.phone_number else "N/A", + "Email": f"{client.email}" if client.email else "N/A", }, } ) - added_client_ids.add(exact_client.id) # To avoid duplicates + added_client_ids.add(client.id) # To avoid duplicates - # Fetch partial matches for Clients - partial_clients = permitted_clients.filter(name__icontains=search_text) - for client in partial_clients: - if client.id not in added_client_ids: # If current ID is not in already found ID's - resources["client"].append( - { - "name": f"{client.name} (#{client.id})", - "url": f"{page_mappings['clients']}{client.id}/", - "details": { - "Phone Number": f"{client.phone_number}" if client.phone_number else "N/A", - "Email": f"{client.email}" if client.email else "N/A", - }, - } - ) - added_client_ids.add(client.id) # To avoid duplicates - - # Save permitted invoices to variable - permitted_invoices = get_permitted_invoices(request) + # Save permitted invoices to variable + permitted_invoices = get_permitted_invoices(request) - if search_text.isdigit(): - # Fetch by ID if it's valid ID - exact_invoice = permitted_invoices.filter(id=int(search_text)).first() - if exact_invoice: - resources["invoice"].append( - { - "name": f"{exact_invoice.client_company} (#{exact_invoice.id})", - "url": f"{page_mappings['invoices single']}{exact_invoice.id}", - "details": { + if search_text.isdigit(): + # Fetch by ID if it's valid ID + exact_invoice = permitted_invoices.filter(id=int(search_text)).first() + if exact_invoice: + resources["invoice"].append( + { + "name": f"{exact_invoice.client_company} (#{exact_invoice.id})", + "url": f"{page_mappings['invoices single']}{exact_invoice.id}", + "details": { + k: v + for k, v in { "Due Date": exact_invoice.date_due.strftime("%d/%m/%Y") if exact_invoice.date_due else "N/A", "Total Amount": ( f"{exact_invoice.get_total_price()} {exact_invoice.currency}" if exact_invoice.get_total_price() else "N/A" ), "Client Name": exact_invoice.client_name, - }, - } - ) + }.items() + if v not in [None, ""] + }, + } + ) + else: + # Fetch exact matches for Invoices + exact_invoice = permitted_invoices.filter(client_name__iexact=search_text) + if exact_invoice: + matched_filter = "client_name" # Save used filter else: - # Fetch exact matches for Invoices - exact_invoice = permitted_invoices.filter(client_name__iexact=search_text) + # If no match for client_name, try client_company + exact_invoice = permitted_invoices.filter(client_company__iexact=search_text) if exact_invoice: - matched_filter = "client_name" # Save used filter - else: - # If no match for client_name, try client_company - exact_invoice = permitted_invoices.filter(client_company__iexact=search_text) - if exact_invoice: - matched_filter = "client_company" - for invoice in exact_invoice: - resources["invoice"].append( - { - "name": f"{invoice.client_name if matched_filter == 'client_name' else invoice.client_company} (#{invoice.id})", - "url": f"{page_mappings['invoices single']}{invoice.id}", - "details": { + matched_filter = "client_company" + for invoice in exact_invoice: + resources["invoice"].append( + { + "name": f"{invoice.client_name if matched_filter == 'client_name' else invoice.client_company} (#{invoice.id})", + "url": f"{page_mappings['invoices single']}{invoice.id}", + "details": { + k: v + for k, v in { "Due Date": invoice.date_due.strftime("%d/%m/%Y") if invoice.date_due else "N/A", "Total Amount": f"{invoice.get_total_price()} {invoice.currency}" if invoice.get_total_price() else "N/A", "Company" if matched_filter == "client_name" else "Client": ( invoice.client_company if matched_filter == "client_name" else invoice.client_name ), - }, - } - ) - added_invoice_ids.add(invoice.id) # To avoid duplicates + }.items() + if v is not None + }, + } + ) + added_invoice_ids.add(invoice.id) # To avoid duplicates - # Fetch partial matches for Invoices - partial_invoices = permitted_invoices.filter(client_name__icontains=search_text) + # Fetch partial matches for Invoices + partial_invoices = permitted_invoices.filter(client_name__icontains=search_text) + if partial_invoices: + matched_filter = "client_name" # Save used filter + else: + # If no match for client_name, try client_company + partial_invoices = permitted_invoices.filter(client_company__icontains=search_text) if partial_invoices: - matched_filter = "client_name" # Save used filter - else: - # If no match for client_name, try client_company - partial_invoices = permitted_invoices.filter(client_company__icontains=search_text) - if partial_invoices: - matched_filter = "client_company" - for invoice in partial_invoices: - if invoice.id not in added_invoice_ids: # If current ID is not in already found ID's - resources["invoice"].append( - { - "name": f"{invoice.client_name if matched_filter == 'client_name' else invoice.client_company} (#{invoice.id})", - "url": f"{page_mappings['invoices single']}{invoice.id}", - "details": { + matched_filter = "client_company" + for invoice in partial_invoices: + if invoice.id not in added_invoice_ids: # If current ID is not in already found ID's + resources["invoice"].append( + { + "name": f"{invoice.client_name if matched_filter == 'client_name' else invoice.client_company} (#{invoice.id})", + "url": f"{page_mappings['invoices single']}{invoice.id}", + "details": { + k: v + for k, v in { "Due Date": invoice.date_due.strftime("%d/%m/%Y") if invoice.date_due else "N/A", "Total Amount": f"{invoice.get_total_price()} {invoice.currency}" if invoice.get_total_price() else "N/A", "Company" if matched_filter == "client_name" else "Client": ( invoice.client_company if matched_filter == "client_name" else invoice.client_name ), - }, - } - ) - added_invoice_ids.add(invoice.id) # To avoid duplicates + }.items() + if v not in [None, ""] + }, + } + ) + added_invoice_ids.add(invoice.id) # To avoid duplicates return render( request, diff --git a/frontend/templates/base/topbar/_search_dropdown.html b/frontend/templates/base/topbar/_search_dropdown.html index 614e2ec98..96e0602e4 100644 --- a/frontend/templates/base/topbar/_search_dropdown.html +++ b/frontend/templates/base/topbar/_search_dropdown.html @@ -1,51 +1,49 @@ -{% load to_list from strfilters %} -
    -
    Results for {{ search }}
    +{% load to_list from strfilters %} +
    + {% if search %}
    Results for '{{ search }}'
    {% endif %} {% if services %} -
    - Services ({{ services | length }}) -
    +
    Services ({{ services | length }})

    {% for service_name, service in services.items %} -
    +
    {{ service_name | title }}
    {{ service.description }}
    -
    -
    - Features -
    - {% for feature_name, url in service.features.items %} - {{ feature_name }} - {% endfor %} + {% if service.features %} +
    +
    + Features +
    + {% for feature_name, url in service.features.items %} + {{ feature_name }} + {% endfor %} +
    -
    + {% endif %}
    {% endfor %}
    {% endif %} {% if resource_count %} -
    - Resources ({{ resource_count }}) -
    +
    Resources ({{ resource_count }})

    {% for resource_type, resource_list in resources.items %} {% for resource in resource_list %} -
    +
    {{ resource.name }}
    {{ resource_type | title }}
    diff --git a/frontend/templates/base/topbar/_topbar.html b/frontend/templates/base/topbar/_topbar.html index 8be142ab5..d34e0625e 100644 --- a/frontend/templates/base/topbar/_topbar.html +++ b/frontend/templates/base/topbar/_topbar.html @@ -64,70 +64,84 @@ {% if feature_enabled_invoices %}
  • - - Invoices - -
  • - {% endif %} -
    -
  • - Clients - -
  • - {% if feature_enabled_monthly_reports %} -
    -
  • - - - Monthly Reports - -
  • - {% endif %} + hx-swap="innerHTML show:no-scroll"> + Invoices + + + {% endif %} +
    +
  • + Clients + +
  • + {% if feature_enabled_monthly_reports %} +
    +
  • + + + Monthly Reports + +
  • + {% endif %} + +
    + From c49b4922810641deced4c29259d298b7c50607cd Mon Sep 17 00:00:00 2001 From: Trey <73353716+TreyWW@users.noreply.github.com> Date: Tue, 26 Nov 2024 22:09:28 +0000 Subject: [PATCH 5/5] Added an if statement for two icons based on resource type (invoice/client) Signed-off-by: Trey <73353716+TreyWW@users.noreply.github.com> --- frontend/templates/base/topbar/_search_dropdown.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/templates/base/topbar/_search_dropdown.html b/frontend/templates/base/topbar/_search_dropdown.html index 96e0602e4..ba530f2d9 100644 --- a/frontend/templates/base/topbar/_search_dropdown.html +++ b/frontend/templates/base/topbar/_search_dropdown.html @@ -39,7 +39,11 @@ {% for resource in resource_list %}
    - + {% if resource_type == "client" %} + + {% elif resource_type == "invoice" %} + + {% endif %}