Repository: Health-Informatics-UoN/Carrot-Mapper

Issue:
Scan Report Index
<!--
INSTRUCTIONS: Please complete all sections detailing an ACTION
-->

# Summary

A test case to reimplement the Scan Report index page in NextJS. This is to test the viability of this approach before rewriting other pages.
This work is needed in order pave the way for revamping other pages and reducing technical debt across the front end and APIs.

# Tasks

- [x] Create Next App
- [x] Local Dev Experience
- [x] Auth
- [x] Page
- [x] CSS Styles
- [x] Fetch scan reports
- [x] Table
- [x] Routing Investigation for Azure
- [x] Deployment
- [x] Fix proxy pages to be limited to `/scanreport/` (probably change the URL ordering)
- [ ] Review

# Acceptance Criteria

- [x] Deployed instance of CARROT with this feature
- [x] Functionality is unchanged
- [x] Appearance is unchanged


Discussion:
Completed in #691 

Resolving patch:
diff --git a/app/api/api/views.py b/app/api/api/views.py
--- a/app/api/api/views.py
+++ b/app/api/api/views.py
@@ -1,6 +1,7 @@
 import logging
 import os
 from typing import Any
+from urllib.parse import urljoin
 
 import requests
 from api.paginations import CustomPagination
@@ -366,6 +367,7 @@ class ScanReportListViewSetV2(ScanReportListViewSet):
     filterset_fields = {"hidden": ["exact"], "dataset": ["in", "icontains"]}
     ordering_fields = ["id", "name", "created_at", "dataset", "data_partner"]
     pagination_class = CustomPagination
+    ordering = "-created_at"
 
     def get_serializer_class(self):
         if self.request.method in ["GET", "POST"]:
@@ -587,9 +589,12 @@ def partial_update(self, request: Any, *args: Any, **kwargs: Any) -> Response:
             "table_id": instance.id,
             "data_dictionary_blob": data_dictionary_name,
         }
-        orchestrator_url = f"{settings.AZ_FUNCTIONS_URL}/api/orchestrators/{settings.AZ_FUNCTIONS_RULES_NAME}"
+        base_url = f"{settings.AZ_URL}"
+        trigger = (
+            f"/api/orchestrators/{settings.AZ_RULES_NAME}?code={settings.AZ_RULES_KEY}"
+        )
         try:
-            response = requests.post(orchestrator_url, json=msg)
+            response = requests.post(urljoin(base_url, trigger), json=msg)
             response.raise_for_status()
         except request.exceptions.HTTPError as e:
             logging.error(f"HTTP Trigger failed: {e}")
diff --git a/app/api/config/settings.py b/app/api/config/settings.py
--- a/app/api/config/settings.py
+++ b/app/api/config/settings.py
@@ -184,5 +184,6 @@
 NEXTJS_URL = os.environ.get("NEXTJS_URL", "http://localhost:3000")
 
 # Azure Functions
-AZ_FUNCTIONS_URL = os.environ.get("AZ_FUNCTIONS_URL", "http://localhost:7071")
-AZ_FUNCTIONS_RULES_NAME = os.environ.get("AZ_FUNCTIONS_RULES_NAME", "RulesOrchestrator")
+AZ_URL = os.environ.get("AZ_URL", "http://localhost:7071")
+AZ_RULES_NAME = os.environ.get("AZ_RULES_NAME", "RulesOrchestrator")
+AZ_RULES_KEY = os.environ.get("AZ_RULES_KEY", "")
diff --git a/app/api/proxy/urls.py b/app/api/proxy/urls.py
--- a/app/api/proxy/urls.py
+++ b/app/api/proxy/urls.py
@@ -6,12 +6,12 @@
 urlpatterns = [
     # /scanreports/ and escape any further paths
     re_path(
-        r"^scanreports/(?P<path>(?![\d/]).*)$",
+        r"^scanreports/(?P<path>(?!create)(?![\d/]).*)$",
         ProxyView.as_view(upstream=f"{settings.NEXTJS_URL}/scanreports"),
         name="scan-report-list",
     ),
     re_path(
-        "datasets/?(?P<path>.*)$",
+        r"^datasets/(?P<path>(?![\d/]).*)$",
         ProxyView.as_view(upstream=f"{settings.NEXTJS_URL}/datasets"),
         name="datasets-list",
     ),


Test patch: