Repository: mathesar-foundation/mathesar

Issue:
Handle routing takeover at client
Currently, routing is handled by Django. When the user visits the application initially, the routing should be handled by Django, and after the application loads, the routing should be taken over by client.


Discussion:

Resolving patch:
diff --git a/mathesar/urls.py b/mathesar/urls.py
--- a/mathesar/urls.py
+++ b/mathesar/urls.py
@@ -14,11 +14,7 @@
 
 urlpatterns = [
     path('', frontend.index, name="index"),
-    path(
-        'tables/<int:pk>/',
-        frontend.TableDetail.as_view(),
-        name='frontend-table-detail',
-    ),
+    path('tables/<int:pk>', frontend.table, name="table"),
     path('api/v0/', include(router.urls)),
     path('api/v0/', include(records_router.urls)),
 ]
diff --git a/mathesar/views/frontend.py b/mathesar/views/frontend.py
--- a/mathesar/views/frontend.py
+++ b/mathesar/views/frontend.py
@@ -1,16 +1,22 @@
-from django.http import HttpResponseRedirect
+from django.http import JsonResponse
 from django.shortcuts import render
-from django.urls import reverse
-from django.views.generic import DetailView
 
 from mathesar.forms.forms import UploadFileForm
 from mathesar.imports.csv import create_table_from_csv
 from mathesar.models import Table, Schema
-from mathesar.serializers import SchemaSerializer
+from mathesar.serializers import SchemaSerializer, TableSerializer, RecordSerializer
+from mathesar.database.utils import get_non_default_database_keys
+
+
+def get_common_data(request):
+    schema_serializer = SchemaSerializer(Schema.objects.all(), many=True, context={'request': request})
+    return {
+        "schemas": schema_serializer.data,
+        "databases": get_non_default_database_keys(),
+    }
 
 
 def index(request):
-    tables = Table.objects.all()
     if request.method == "POST":
         form = UploadFileForm(request.POST, request.FILES)
         if form.is_valid():
@@ -20,23 +26,32 @@ def index(request):
                 database_key=form.cleaned_data["database_key"],
                 csv_file=request.FILES["file"]
             )
-            return HttpResponseRedirect(
-                reverse("frontend-table-detail", kwargs={"pk": table.id})
-            )
-    else:
-        form = UploadFileForm()
-    schema_serializer = SchemaSerializer(Schema.objects.all(), many=True, context={'request': request})
+            return JsonResponse({"pk": table.id}, status=200)
     return render(
         request,
         "mathesar/index.html",
         {
-            "form": form,
-            "tables": sorted(tables, key=lambda x: x.schema.name),
-            "schema_data": schema_serializer.data
-        },
+            "common_data": get_common_data(request),
+        }
     )
 
 
-class TableDetail(DetailView):
-    context_object_name = "table"
-    queryset = Table.objects.all()
+def table(request, pk):
+    try:
+        table_data = Table.objects.get(pk=pk)
+        table_serialized = TableSerializer(table_data, context={'request': request}).data
+        records_serialized = RecordSerializer(table_data.get_records(limit=50, offset=0), many=True, context={'request': request}).data
+    except Table.DoesNotExist:
+        table_serialized = {}
+        records_serialized = []
+    return render(
+        request,
+        "mathesar/index.html",
+        {
+            "common_data": get_common_data(request),
+            "route_specific_data": {
+                "table-detail": table_serialized,
+                "table-records": records_serialized
+            }
+        }
+    )


Test patch:
diff --git a/mathesar_ui/src/__tests__/App.test.js b/mathesar_ui/src/__tests__/App.test.js
--- a/mathesar_ui/src/__tests__/App.test.js
+++ b/mathesar_ui/src/__tests__/App.test.js
@@ -1,9 +1,28 @@
 import '@testing-library/jest-dom/extend-expect';
 import { render } from '@testing-library/svelte';
-import App from '../App';
+import App from '../App.svelte';
+
+function addCommonDataScript() {
+  const commonDataScript = document.createElement('script');
+  commonDataScript.id = 'common-data';
+  commonDataScript.type = 'application/json';
+  commonDataScript.textContent = JSON.stringify({
+    schemas: [],
+    databases: ['mathesar_tables'],
+  });
+  document.body.append(commonDataScript);
+}
+
+function removeCommonDataScript() {
+  const commonDataScript = document.querySelector('#common-data');
+  if (commonDataScript) {
+    commonDataScript.remove();
+  }
+}
 
 test('shows mathesar default text when rendered', () => {
+  addCommonDataScript();
   const { getByText } = render(App, {});
-
-  expect(getByText('Mathesar - Rendered from Svelte')).toBeInTheDocument();
+  expect(getByText('mathesar_tables')).toBeInTheDocument();
+  removeCommonDataScript();
 });