diff --git a/src/frontend/apps/lti_site/data/queries/index.tsx b/src/frontend/apps/lti_site/data/queries/index.tsx index 6af7dd8d6a..b4a0411962 100644 --- a/src/frontend/apps/lti_site/data/queries/index.tsx +++ b/src/frontend/apps/lti_site/data/queries/index.tsx @@ -127,7 +127,7 @@ export const useThumbnail = ( videoId: string, queryConfig?: UseQueryOptions, ) => { - const key = ['videos', videoId, `thumbnails/${thumbnailId}`]; + const key = [`videos/${videoId}/thumbnails`, thumbnailId]; return useQuery({ queryKey: key, queryFn: fetchOne, diff --git a/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.spec.tsx b/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.spec.tsx index 4f31b0e232..3188d65b6b 100644 --- a/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.spec.tsx +++ b/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.spec.tsx @@ -14,7 +14,7 @@ import { Thumbnail, Video } from '@lib-components/types/tracks'; import { UploadHandlers } from './UploadHandlers'; -import { UploadManagerContext, UploadManagerStatus } from '.'; +import { UploadManagerContext, UploadManagerStatus, UploadingObject } from '.'; jest.mock('data/sideEffects/updateResource', () => ({ updateResource: jest.fn(), @@ -36,7 +36,7 @@ const mockGetResource = getStoreResource as jest.MockedFunction< const mockUpdateResource = updateResource as jest.MockedFunction< typeof updateResource >; -const mockFetResource = fetchResource as jest.MockedFunction< +const mockFetchResource = fetchResource as jest.MockedFunction< typeof fetchResource >; @@ -99,6 +99,8 @@ describe('', () => { title: file.name, }, modelName.VIDEOS, + undefined, + undefined, ); }); @@ -143,7 +145,7 @@ describe('', () => { }); it('fetch the resource when the upload manager status is UPLOADING', async () => { - mockFetResource.mockResolvedValue(object); + mockFetchResource.mockResolvedValue(object); const { rerender } = render( ', () => { , ); - expect(mockFetResource).not.toHaveBeenCalled(); + expect(mockFetchResource).not.toHaveBeenCalled(); rerender( ', () => { ); await waitFor(() => { - expect(mockFetResource).toHaveBeenCalledWith(modelName.VIDEOS, object.id); + expect(mockFetchResource).toHaveBeenCalledWith( + modelName.VIDEOS, + object.id, + undefined, + undefined, + ); + }); + }); + + it('fetch the resource with parent resource', async () => { + const image = new File(['(⌐□_□)'], 'course.jpg', { type: 'image/jpeg' }); + const thumbnailState = { + file: image, + objectId: uuidv4(), + objectType: modelName.THUMBNAILS, + progress: 0, + status: UploadManagerStatus.UPLOADING, + parentId: uuidv4(), + parentType: modelName.VIDEOS as UploadingObject['parentType'], + }; + const thumbnail = { id: thumbnailState.objectId } as Thumbnail; + mockFetchResource.mockResolvedValue(thumbnail); + + const { rerender } = render( + {}, + uploadManagerState: { + [thumbnailState.objectId]: { + ...thumbnailState, + status: UploadManagerStatus.INIT, + }, + }, + }} + > + + , + ); + + expect(mockFetchResource).not.toHaveBeenCalled(); + + rerender( + {}, + uploadManagerState: { + [thumbnailState.objectId]: { + ...thumbnailState, + status: UploadManagerStatus.UPLOADING, + }, + }, + }} + > + + , + ); + + await waitFor(() => { + expect(mockFetchResource).toHaveBeenCalledWith( + modelName.THUMBNAILS, + thumbnail.id, + modelName.VIDEOS, + thumbnailState.parentId, + ); }); }); diff --git a/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.tsx b/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.tsx index 469761d696..30090e4996 100644 --- a/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.tsx +++ b/src/frontend/packages/lib_components/src/common/UploadManager/UploadHandlers.tsx @@ -14,7 +14,8 @@ const UploadSuccessHandler = ({ }: { objectState: UploadManagerState[string]; }) => { - const { status, file, objectId, objectType } = objectState; + const { status, file, objectId, objectType, parentId, parentType } = + objectState; // once upload on S3 is finished, push new state to backend useEffect(() => { @@ -40,10 +41,12 @@ const UploadSuccessHandler = ({ title: file.name, }, objectType, + parentId, + parentType, ); } })(); - }, [file.name, objectId, objectType, status]); + }, [file.name, objectId, objectType, parentId, parentType, status]); // update the ressource beeing uploaded useEffect(() => { @@ -52,9 +55,9 @@ const UploadSuccessHandler = ({ return; } - await fetchResource(objectType, objectId); + await fetchResource(objectType, objectId, parentType, parentId); })(); - }, [objectId, objectType, status]); + }, [objectId, objectType, parentId, parentType, status]); return null; }; diff --git a/src/frontend/packages/lib_components/src/data/sideEffects/getResource/index.tsx b/src/frontend/packages/lib_components/src/data/sideEffects/getResource/index.tsx index d7c1b76d9e..c477292b0b 100644 --- a/src/frontend/packages/lib_components/src/data/sideEffects/getResource/index.tsx +++ b/src/frontend/packages/lib_components/src/data/sideEffects/getResource/index.tsx @@ -1,3 +1,6 @@ +import { Maybe } from '@lib-common/types'; + +import { UploadingObject } from '@lib-components/common'; import { fetchWrapper } from '@lib-components/common/queries/fetchWrapper'; import { addResource } from '@lib-components/data/stores/generics'; import { useJwt } from '@lib-components/hooks/stores/useJwt'; @@ -16,8 +19,13 @@ import { report } from '@lib-components/utils/errors/report'; export async function getResource( resourceName: uploadableModelName, resourceId: string, + parentType?: Maybe, + parentId?: Maybe, ): Promise { - const endpoint = `${API_ENDPOINT}/${resourceName}/${resourceId}/`; + let endpoint = `${API_ENDPOINT}/${resourceName}/${resourceId}/`; + if (parentId && parentType) { + endpoint = `${API_ENDPOINT}/${parentType}/${parentId}/${resourceName}/${resourceId}/`; + } try { const response = await fetchWrapper(endpoint, { diff --git a/src/frontend/packages/lib_components/src/data/sideEffects/updateResource/index.ts b/src/frontend/packages/lib_components/src/data/sideEffects/updateResource/index.ts index d14ce1ae0b..1caccdb643 100644 --- a/src/frontend/packages/lib_components/src/data/sideEffects/updateResource/index.ts +++ b/src/frontend/packages/lib_components/src/data/sideEffects/updateResource/index.ts @@ -1,3 +1,6 @@ +import { Maybe } from '@lib-common/types'; + +import { UploadingObject } from '@lib-components/common'; import { fetchWrapper } from '@lib-components/common/queries/fetchWrapper'; import { useJwt } from '@lib-components/hooks/stores'; import { API_ENDPOINT } from '@lib-components/settings'; @@ -7,8 +10,13 @@ import { Resource } from '@lib-components/types/tracks'; export async function updateResource( resource: R, resourceName: uploadableModelName, + parentId?: Maybe, + parentType?: Maybe, ): Promise { - const endpoint = `${API_ENDPOINT}/${resourceName}/${resource.id}/`; + let endpoint = `${API_ENDPOINT}/${resourceName}/${resource.id}/`; + if (parentId && parentType) { + endpoint = `${API_ENDPOINT}/${parentType}/${parentId}/${resourceName}/${resource.id}/`; + } const response = await fetchWrapper(endpoint, { body: JSON.stringify(resource), diff --git a/src/frontend/packages/lib_components/src/data/stores/generics.ts b/src/frontend/packages/lib_components/src/data/stores/generics.ts index 6cf355e821..a3b7ccb1d4 100644 --- a/src/frontend/packages/lib_components/src/data/stores/generics.ts +++ b/src/frontend/packages/lib_components/src/data/stores/generics.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-explicit-any */ + import { ClassroomModelName } from '@lib-components/types/apps/classroom/models'; import { FileDepositoryModelName } from '@lib-components/types/apps/deposit/models'; import { MarkdownDocumentModelName } from '@lib-components/types/apps/markdown/models';