Skip to content

Commit

Permalink
Fix failing detail views
Browse files Browse the repository at this point in the history
  • Loading branch information
monsieurswag committed May 15, 2024
1 parent fa6e99c commit 08d0ba5
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 53 deletions.
68 changes: 51 additions & 17 deletions backend/library/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from rest_framework import viewsets, status
from rest_framework.status import (
HTTP_200_OK,
HTTP_204_NO_CONTENT,
HTTP_400_BAD_REQUEST,
HTTP_403_FORBIDDEN,
HTTP_404_NOT_FOUND,
HTTP_422_UNPROCESSABLE_ENTITY,
)
Expand Down Expand Up @@ -48,9 +50,31 @@ def get_serializer_class(self):
return StoredLibrarySerializer
return StoredLibraryDetailedSerializer

def retrieve(self, request, *args, pk, **kwargs):
if "view_storedlibrary" not in request.user.permissions:
return Response(status=HTTP_403_FORBIDDEN)
try:
lib = StoredLibrary.objects.get(
urn=pk
) # There is no "locale" value involved in the fetch + we have to handle the exception if the pk urn doesn't exist
except:
return Response(data="Library not found.", status=HTTP_404_NOT_FOUND)
data = StoredLibrarySerializer(lib).data
return Response(data)

def content(self, request, pk):
try :
lib = StoredLibrary.objects.get(urn=pk)
except :
return Response("Library not found.", status=HTTP_404_NOT_FOUND)
return Response(lib.content)

@action(detail=True, methods=["get"])
def content(self, request, pk):
lib = StoredLibrary.objects.get(id=pk)
try :
lib = StoredLibrary.objects.get(urn=pk)
except :
return Response("Library not found.", status=HTTP_404_NOT_FOUND)
return Response(lib.content)

def destroy(self, request, *args, pk, **kwargs):
Expand All @@ -59,15 +83,15 @@ def destroy(self, request, *args, pk, **kwargs):
perm=Permission.objects.get(codename="delete_storedlibrary"),
folder=Folder.get_root_folder(),
):
return Response(status=status.HTTP_403_FORBIDDEN)
return Response(status=HTTP_403_FORBIDDEN)

try:
lib = StoredLibrary.objects.get(urn=pk)
except:
return Response(data="Library not found.", status=status.HTTP_404_NOT_FOUND)
return Response(data="Library not found.", status=HTTP_404_NOT_FOUND)

lib.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(status=HTTP_204_NO_CONTENT)

@action(detail=True, methods=["get"], url_path="import")
def import_library(self, request, pk):
Expand All @@ -76,20 +100,20 @@ def import_library(self, request, pk):
perm=Permission.objects.get(codename="add_loadedlibrary"),
folder=Folder.get_root_folder(),
):
return Response(status=status.HTTP_403_FORBIDDEN)
return Response(status=HTTP_403_FORBIDDEN)
try:
library = StoredLibrary.objects.get(
urn=pk
) # This is only fetching the lib by URN without caring about the locale or the version, this must change in the future.
except:
return Response(data="Library not found.", status=status.HTTP_404_NOT_FOUND)
return Response(data="Library not found.", status=HTTP_404_NOT_FOUND)

try:
error_msg = library.load()
if error_msg is not None:
return Response(
{"status": "error", "error": error_msg},
status=status.HTTP_400_BAD_REQUEST,
status=HTTP_400_BAD_REQUEST,
) # This can cause translation issues
return Response({"status": "success"})
except Exception:
Expand All @@ -103,16 +127,17 @@ def import_library(self, request, pk):
@action(detail=True, methods=["get"])
def tree(self, request, pk):
try:
lib = StoredLibrary.objects.get(id=pk)
lib = StoredLibrary.objects.get(urn=pk)
except:
return Response(data="Library not found.", status=status.HTTP_404_NOT_FOUND)
return Response(data="Library not found.", status=HTTP_404_NOT_FOUND)

library_objects = json.loads(lib.content) # We may need caching for this
if not (framework := library_objects.get("framework")):
return Response(
data="This library does not include a framework.",
status=HTTP_400_BAD_REQUEST,
)

preview = preview_library(framework)
return Response(
get_sorted_requirement_nodes(preview.get("requirement_nodes"), None)
Expand Down Expand Up @@ -165,7 +190,7 @@ class LoadedLibraryViewSet(viewsets.ModelViewSet):

def list(self, request, *args, **kwargs):
if "view_storedlibrary" not in request.user.permissions:
return Response(status=status.HTTP_403_FORBIDDEN)
return Response(status=HTTP_403_FORBIDDEN)

loaded_libraries = [
{
Expand All @@ -191,13 +216,13 @@ def list(self, request, *args, **kwargs):

def retrieve(self, request, *args, pk, **kwargs):
if "view_loadedlibrary" not in request.user.permissions:
return Response(status=status.HTTP_403_FORBIDDEN)
return Response(status=HTTP_403_FORBIDDEN)
try:
lib = LoadedLibrary.objects.get(
urn=pk
) # There is no "locale" value involved in the fetch + we have to handle the exception if the pk urn doesn't exist
except:
return Response(data="Library not found.", status=status.HTTP_404_NOT_FOUND)
return Response(data="Library not found.", status=HTTP_404_NOT_FOUND)
data = LoadedLibraryDetailedSerializer(lib).data
data["objects"] = lib._objects
return Response(data)
Expand All @@ -208,30 +233,39 @@ def destroy(self, request, *args, pk, **kwargs):
perm=Permission.objects.get(codename="delete_loadedlibrary"),
folder=Folder.get_root_folder(),
):
return Response(status=status.HTTP_403_FORBIDDEN)
return Response(status=HTTP_403_FORBIDDEN)

try:
lib = LoadedLibrary.objects.get(urn=pk)
except:
return Response(data="Library not found.", status=status.HTTP_404_NOT_FOUND)
return Response(data="Library not found.", status=HTTP_404_NOT_FOUND)

if lib.reference_count != 0:
return Response(
data="Library cannot be deleted because it has references.",
status=status.HTTP_400_BAD_REQUEST,
status=HTTP_400_BAD_REQUEST,
)

lib.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(status=HTTP_204_NO_CONTENT)

@action(detail=True, methods=["get"])
def content(self, request, pk):
try :
lib = LoadedLibrary.objects.get(urn=pk)
except :
return Response("Library not found.", status=HTTP_404_NOT_FOUND)
return Response(lib._objects)

@action(detail=True, methods=["get"])
def tree(
self, request, pk
): # We must ensure that users that are not allowed to read the content of libraries can't have any access to them either from the /api/{URLModel/{library_urn}/tree view or the /api/{URLModel}/{library_urn} view.

try:
lib = LoadedLibrary.objects.get(urn=pk)
except:
return Response(data="Library not found.", status=status.HTTP_404_NOT_FOUND)
return Response(data="Library not found.", status=HTTP_404_NOT_FOUND)

if lib.frameworks.count() == 0:
return Response(
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/lib/components/ModelTable/ModelTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
const rowMetaData = $rows[rowIndex].meta;
/** @event {rowMetaData} selected - Fires when a table row is clicked. */
if (!rowMetaData[identifierField] || !URLModel) return;
goto(`/${URLModel}/${rowMetaData[identifierField]}`);
goto(`/${URLModel}/${rowMetaData[identifierField]}${detailQueryParameter}`);
}
// Row Keydown Handler
Expand All @@ -84,10 +84,10 @@
}
export let identifierField = 'id';
export let deleteForm: SuperValidated<AnyZodObject> | undefined = undefined;
export let URLModel: urlModel | undefined = undefined;
export let detailQueryParameter: string | undefined ;
detailQueryParameter = detailQueryParameter ? `?${detailQueryParameter}` : "";
const user = $page.data.user;
Expand Down Expand Up @@ -133,7 +133,7 @@
$: model = source.meta?.urlmodel ? URL_MODEL_MAP[source.meta.urlmodel] : URL_MODEL_MAP[URLModel];
$: source, handler.setRows(data);
const actionsURLModel = source.meta.urlmodel ?? URLModel;
const actionsURLModel = source.meta?.urlmodel ?? URLModel;
const preventDelete = (row: TableSource) =>
(row.meta.builtin && actionsURLModel !== 'loaded-libraries') ||
(Object.hasOwn(row.meta, 'reference_count') && row.meta.reference_count > 0);
Expand Down Expand Up @@ -272,7 +272,7 @@
deleteForm={deleteForm}
{model}
URLModel={actionsURLModel}
detailURL={`/${actionsURLModel}/${row.meta[identifierField]}`}
detailURL={`/${actionsURLModel}/${row.meta[identifierField]}${detailQueryParameter}`}
editURL={!(row.meta.builtin || row.meta.urn) ? `/${actionsURLModel}/${row.meta[identifierField]}/edit?next=${$page.url.pathname}` : undefined}
{row}
hasBody={$$slots.actionsBody}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/routes/(app)/libraries/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
identifierField="urn"
pagination={false}
deleteForm={data.deleteForm}
detailQueryParameter="loaded"
/>
{/if}
</svelte:fragment>
Expand Down
25 changes: 11 additions & 14 deletions frontend/src/routes/(app)/libraries/[id=urn]/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,20 @@ import type { RequestHandler } from './$types';
export const GET: RequestHandler = async ({ fetch, url, params }) => {
const isLoaded = url.searchParams.has('loaded');
const URLModel = isLoaded ? 'loaded-libraries' : 'stored-libraries';
const endpoint = `${BASE_API_URL}/${URLModel}/?urn=${params.id}`;
const endpoint = `${BASE_API_URL}/${URLModel}/${params.id}/`;
const contentEndpoint = `${BASE_API_URL}/${URLModel}/${params.id}/content`;

const res = await fetch(endpoint);
if (!res.ok) {
error(res.status as NumericRange<400, 599>, await res.json());
}
const data = await res
.json()
.then((res) => res.results)
.then((res) => res.reduce((acc, curr) => (acc.version > curr.version ? acc : curr))); // Get the latest version of the library
const [res,contentRes] = await Promise.all([
fetch(endpoint),
fetch(contentEndpoint)
]);

const uuid = data.id;
const contentEndpoint = `${BASE_API_URL}/${URLModel}/${uuid}/content`;
const contentRes = await fetch(contentEndpoint);
if (!contentRes.ok) {
if (!res.ok)
error(res.status as NumericRange<400, 599>, await res.json());
if (!contentRes.ok)
error(contentRes.status as NumericRange<400, 599>, await contentRes.json());
}

const data = await res.json()
const content = await contentRes.json();
data.objects = content;
if (!isLoaded) {
Expand Down
21 changes: 4 additions & 17 deletions frontend/src/routes/(app)/libraries/[id=urn]/tree/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,13 @@ import type { RequestHandler } from './$types';

export const GET: RequestHandler = async ({ fetch, params, url }) => {
const URLModel = url.searchParams.has('loaded') ? 'loaded-libraries' : 'stored-libraries';
const endpoint = `${BASE_API_URL}/${URLModel}/?urn=${params.id}`;

const endpoint = `${BASE_API_URL}/${URLModel}/${params.id}/tree`;
const res = await fetch(endpoint);
if (!res.ok) {
error(res.status as NumericRange<400, 599>, await res.json());
}
const data = await res
.json()
.then((res) => res.results)
.then((res) => res.reduce((acc, curr) => (acc.version > curr.version ? acc : curr))); // Get the latest version of the library

const uuid = data.id;
const treeEndpoint = `${BASE_API_URL}/${URLModel}/${uuid}/tree`;
const treeRes = await fetch(treeEndpoint);
if (!treeRes.ok) {
error(treeRes.status as NumericRange<400, 599>, await treeRes.json());
}

const tree = await treeRes.json();
if (!res.ok)
error(res.status as NumericRange<400, 599>, await res.json());

const tree = await res.json();
return new Response(JSON.stringify(tree), {
headers: {
'Content-Type': 'application/json'
Expand Down

0 comments on commit 08d0ba5

Please sign in to comment.