From d6a69955ff9039478c5e1fec58af0bb1fabbebb3 Mon Sep 17 00:00:00 2001 From: David Ly Date: Wed, 19 Feb 2025 14:54:30 +0100 Subject: [PATCH] Added autovalidate compliant inspections --- .../src/PhotoCapture/PhotoCapture.tsx | 34 +++---- .../PhotoCaptureHUD/PhotoCaptureHUD.tsx | 1 - .../PhotoCaptureHUDElements.tsx | 6 +- .../src/PhotoCapture/hooks/index.ts | 1 + .../hooks/useInspectionComplete.ts | 82 +++++++++++++++++ .../hooks/usePhotoCaptureSightGuidelines.ts | 4 - .../hooks/usePhotoCaptureSightState.ts | 61 +++++++++---- .../HUDOverlay/HUDOverlay.styles.ts | 2 +- .../src/hooks/useStartTasksOnComplete.ts | 8 +- .../test/PhotoCapture/PhotoCapture.test.tsx | 88 ++++++------------- .../PhotoCaptureHUD/PhotoCaptureHUD.test.tsx | 1 - .../PhotoCaptureHUDElements.test.tsx | 11 --- .../hooks/usePhotoCaptureSightState.test.ts | 2 + .../test/components/HUDOverlay.test.tsx | 2 +- packages/types/src/config.ts | 2 +- 15 files changed, 181 insertions(+), 124 deletions(-) create mode 100644 packages/inspection-capture-web/src/PhotoCapture/hooks/useInspectionComplete.ts diff --git a/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx b/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx index cfa3b4495..ad9730dae 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx +++ b/packages/inspection-capture-web/src/PhotoCapture/PhotoCapture.tsx @@ -1,13 +1,12 @@ import { useAnalytics } from '@monkvision/analytics'; import { Camera, CameraHUDProps } from '@monkvision/camera-web'; -import { useI18nSync, useLoadingState, useObjectMemo, usePreventExit } from '@monkvision/common'; +import { useI18nSync, useLoadingState, useObjectMemo } from '@monkvision/common'; import { BackdropDialog, InspectionGallery, NavigateToCaptureOptions, NavigateToCaptureReason, } from '@monkvision/common-ui-web'; -import { useMonitoring } from '@monkvision/monitoring'; import { MonkApiConfig } from '@monkvision/network'; import { AddDamage, @@ -39,6 +38,7 @@ import { usePhotoCaptureSightState, usePhotoCaptureTutorial, usePhotoCaptureSightGuidelines, + useInspectionComplete, } from './hooks'; /** @@ -158,7 +158,6 @@ export function PhotoCapture({ customComplianceThresholdsPerSight, }); const { t } = useTranslation(); - const monitoring = useMonitoring(); const [currentScreen, setCurrentScreen] = useState(PhotoCaptureScreen.CAMERA); const analytics = useAnalytics(); const loading = useLoadingState(); @@ -198,6 +197,8 @@ export function PhotoCapture({ tasksBySight, complianceOptions, setIsInitialInspectionFetched, + startTasksOnComplete, + onComplete, }); const { currentTutorialStep, goToNextTutorialStep, closeTutorial } = usePhotoCaptureTutorial({ enableTutorial, @@ -227,6 +228,13 @@ export function PhotoCapture({ tasksBySight, onPictureTaken, }); + const { handleInspectionCompleted } = useInspectionComplete({ + startTasks, + sightState, + loading, + startTasksOnComplete, + onComplete, + }); const handleGalleryBack = () => setCurrentScreen(PhotoCaptureScreen.CAMERA); const handleNavigateToCapture = (options: NavigateToCaptureOptions) => { if (options.reason === NavigateToCaptureReason.ADD_DAMAGE) { @@ -242,24 +250,6 @@ export function PhotoCapture({ } setCurrentScreen(PhotoCaptureScreen.CAMERA); }; - const { allowRedirect } = usePreventExit(sightState.sightsTaken.length !== 0); - const handleGalleryValidate = () => { - startTasks() - .then(() => { - analytics.trackEvent('Capture Completed'); - analytics.setUserProperties({ - captureCompleted: true, - sightSelected: 'inspection-completed', - }); - allowRedirect(); - onComplete?.(); - sightState.setIsInspectionCompleted(true); - }) - .catch((err) => { - loading.onError(err); - monitoring.handleError(err); - }); - }; const hudProps: Omit = { sights, selectedSight: sightState.selectedSight, @@ -313,7 +303,7 @@ export function PhotoCapture({ allowSkipRetake={allowSkipRetake} onBack={handleGalleryBack} onNavigateToCapture={handleNavigateToCapture} - onValidate={handleGalleryValidate} + onValidate={handleInspectionCompleted} addDamage={addDamage} validateButtonLabel={validateButtonLabel} isInspectionCompleted={sightState.isInspectionCompleted} diff --git a/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.tsx b/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.tsx index 3801e4110..3d83a0a17 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.tsx +++ b/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.tsx @@ -205,7 +205,6 @@ export function PhotoCaptureHUD({ onSelectSight={onSelectSight} onRetakeSight={onRetakeSight} onValidateVehicleParts={onValidateVehicleParts} - isLoading={loading.isLoading} error={loading.error ?? handle.error} previewDimensions={handle.previewDimensions} images={images} diff --git a/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements/PhotoCaptureHUDElements.tsx b/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements/PhotoCaptureHUDElements.tsx index 8078e860e..b1bfb421f 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements/PhotoCaptureHUDElements.tsx +++ b/packages/inspection-capture-web/src/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements/PhotoCaptureHUDElements.tsx @@ -72,10 +72,6 @@ export interface PhotoCaptureHUDElementsProps * The effective pixel dimensions of the Camera video stream on the screen. */ previewDimensions: PixelDimensions | null; - /** - * Boolean indicating if the global loading state of the PhotoCapture component is loading or not. - */ - isLoading?: boolean; /** * The error that occurred in the PhotoCapture component. Set this value to `null` if there is no error. */ @@ -98,7 +94,7 @@ export interface PhotoCaptureHUDElementsProps * Component implementing an HUD displayed on top of the Camera preview during the PhotoCapture process. */ export function PhotoCaptureHUDElements(params: PhotoCaptureHUDElementsProps) { - if (params.isLoading || !!params.error) { + if (params.error) { return null; } if (params.mode === CaptureMode.SIGHT) { diff --git a/packages/inspection-capture-web/src/PhotoCapture/hooks/index.ts b/packages/inspection-capture-web/src/PhotoCapture/hooks/index.ts index 823329949..83906e74f 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/hooks/index.ts +++ b/packages/inspection-capture-web/src/PhotoCapture/hooks/index.ts @@ -2,3 +2,4 @@ export * from './usePhotoCaptureSightState'; export * from './useComplianceAnalytics'; export * from './usePhotoCaptureTutorial'; export * from './usePhotoCaptureSightGuidelines'; +export * from './useInspectionComplete'; diff --git a/packages/inspection-capture-web/src/PhotoCapture/hooks/useInspectionComplete.ts b/packages/inspection-capture-web/src/PhotoCapture/hooks/useInspectionComplete.ts new file mode 100644 index 000000000..9c9b43507 --- /dev/null +++ b/packages/inspection-capture-web/src/PhotoCapture/hooks/useInspectionComplete.ts @@ -0,0 +1,82 @@ +import { LoadingState, useObjectMemo, usePreventExit } from '@monkvision/common'; +import { useCallback, useEffect } from 'react'; +import { useAnalytics } from '@monkvision/analytics'; +import { useMonitoring } from '@monkvision/monitoring'; +import { PhotoCaptureAppConfig } from '@monkvision/types'; +import { StartTasksFunction } from '../../hooks'; +import { PhotoCaptureSightState } from './usePhotoCaptureSightState'; + +/** + * Parameters of the useInspectionComplete hook. + */ +export interface InspectionCompleteParams + extends Pick { + /** + * Callback called when the user has started the inspection tasks. + */ + startTasks: StartTasksFunction; + /** + * The sight state, created using the usePhotoCaptureSightState hook. + */ + sightState: PhotoCaptureSightState; + /** + * Global loading state of the PhotoCapture component. + */ + loading: LoadingState; + /** + * Callback called when the user clicks on the "Complete" button in the HUD. + */ + onComplete?: () => void; +} + +/** + * Handle used to manage the completion of the inspection. + */ +export interface InspectionCompleteHandle { + /** + * Callback called when the user has completed the inspection. + */ + handleInspectionCompleted: () => void; +} + +/** + * Custom hook used to generate the callback called when the user has completed the inspection. + */ +export function useInspectionComplete({ + startTasks, + sightState, + loading, + startTasksOnComplete, + onComplete, +}: InspectionCompleteParams): InspectionCompleteHandle { + const analytics = useAnalytics(); + const monitoring = useMonitoring(); + const { allowRedirect } = usePreventExit(sightState.sightsTaken.length !== 0); + + const handleInspectionCompleted = useCallback(() => { + startTasks() + .then(() => { + analytics.trackEvent('Capture Completed'); + analytics.setUserProperties({ + captureCompleted: true, + sightSelected: 'inspection-completed', + }); + allowRedirect(); + onComplete?.(); + sightState.setIsInspectionCompleted(true); + }) + .catch((err) => { + loading.onError(err); + monitoring.handleError(err); + }); + }, []); + + useEffect(() => { + const { isInspectionCompliant, isInspectionCompleted } = sightState; + if (startTasksOnComplete && isInspectionCompliant && !isInspectionCompleted) { + handleInspectionCompleted(); + } + }, [sightState.isInspectionCompliant]); + + return useObjectMemo({ handleInspectionCompleted }); +} diff --git a/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightGuidelines.ts b/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightGuidelines.ts index 7b038cea3..96002ae89 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightGuidelines.ts +++ b/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightGuidelines.ts @@ -7,10 +7,6 @@ export const TTL_MS = 48 * 60 * 60 * 1000; function isTTLExpired(): boolean { const timestamp = localStorage.getItem(STORAGE_KEY_PHOTO_CAPTURE_GUIDELINES); - if (timestamp) { - console.log(Date.now() - parseInt(timestamp, 10) > TTL_MS); - } - return !timestamp || Date.now() - parseInt(timestamp, 10) > TTL_MS; } diff --git a/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightState.ts b/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightState.ts index 43c5c4143..d0549a8a9 100644 --- a/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightState.ts +++ b/packages/inspection-capture-web/src/PhotoCapture/hooks/usePhotoCaptureSightState.ts @@ -1,4 +1,4 @@ -import { Dispatch, SetStateAction, useCallback, useState } from 'react'; +import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react'; import { GetInspectionResponse, MonkApiConfig, @@ -9,6 +9,7 @@ import { useMonitoring } from '@monkvision/monitoring'; import { getInspectionImages, LoadingState, + MonkState, uniq, useAsyncEffect, useMonkState, @@ -21,6 +22,7 @@ import { TaskName, ImageStatus, ProgressStatus, + PhotoCaptureAppConfig, } from '@monkvision/types'; import { sights } from '@monkvision/sights'; import { useAnalytics } from '@monkvision/analytics'; @@ -70,12 +72,17 @@ export interface PhotoCaptureSightState { * Callback used to manually update the completion state of the inspection. */ setIsInspectionCompleted: Dispatch>; + /** + * Boolean indicating if the inspection is compliant or not. + */ + isInspectionCompliant: boolean; } /** * Parameters of the usePhotoCaptureSightState hook. */ -export interface PhotoCaptureSightsParams { +export interface PhotoCaptureSightsParams + extends Pick { /** * The inspection ID. */ @@ -109,6 +116,10 @@ export interface PhotoCaptureSightsParams { * sight will be used. */ tasksBySight?: Record; + /** + * Callback called when inspection capture is complete. + */ + onComplete?: () => void; } function getCaptureTasks( @@ -174,6 +185,23 @@ function getLastPictureTakenUri( return images && images.length > 0 ? images[images.length - 1].path : null; } +function getNotCompliantSights( + inspectionId: string, + captureSights: Sight[], + entities: MonkState, + notCompliantStatus = [ImageStatus.NOT_COMPLIANT, ImageStatus.UPLOAD_FAILED], +) { + return captureSights + .map((s) => ({ + sight: s, + image: getInspectionImages(inspectionId, entities.images, undefined, true).find( + (i) => i.inspectionId === inspectionId && i.sightId === s.id, + ), + })) + .filter(({ image }) => !!image && notCompliantStatus.includes(image.status)) + .map(({ sight }) => sight); +} + /** * Custom hook used to manage the state of the PhotoCapture sights. This state is automatically fetched from the API at * the start of the PhotoCapture process in order to allow users to start the inspection where they left it before. @@ -187,6 +215,8 @@ export function usePhotoCaptureSightState({ tasksBySight, setIsInitialInspectionFetched, complianceOptions, + startTasksOnComplete, + onComplete, }: PhotoCaptureSightsParams): PhotoCaptureSightState { if (captureSights.length === 0) { throw new Error('Empty sight list given to the Monk PhotoCapture component.'); @@ -223,19 +253,7 @@ export function usePhotoCaptureSightState({ setSelectedSight(notCapturedSights[0]); } else { onLastSightTaken(); - const notCompliantSights = captureSights - .map((s) => ({ - sight: s, - image: getInspectionImages(inspectionId, state.images, undefined, true).find( - (i) => i.inspectionId === inspectionId && i.sightId === s.id, - ), - })) - .filter( - ({ image }) => - !!image && - [ImageStatus.NOT_COMPLIANT, ImageStatus.UPLOAD_FAILED].includes(image.status), - ) - .map(({ sight }) => sight); + const notCompliantSights = getNotCompliantSights(inspectionId, captureSights, state); const sightToRetake = notCompliantSights.length > 0 ? notCompliantSights[0] @@ -281,6 +299,16 @@ export function usePhotoCaptureSightState({ setRetryCount((value) => value + 1); }, []); + const isInspectionCompliant = useMemo(() => { + const notCapturedSights = captureSights.filter((s) => !sightsTaken.includes(s)); + const notCompliantSights = getNotCompliantSights(inspectionId, captureSights, state, [ + ImageStatus.UPLOADING, + ImageStatus.NOT_COMPLIANT, + ImageStatus.UPLOAD_FAILED, + ]); + return !notCapturedSights.length && !notCompliantSights.length; + }, [state.images]); + const takeSelectedSight = useCallback(() => { const isRetake = sightsTaken.includes(selectedSight); const updatedSightsTaken = isRetake ? sightsTaken : [...sightsTaken, selectedSight]; @@ -302,7 +330,7 @@ export function usePhotoCaptureSightState({ }); if (nextSight) { setSelectedSight(nextSight); - } else { + } else if (!startTasksOnComplete || !onComplete) { onLastSightTaken(); } }, [sightsTaken, selectedSight, captureSights, onLastSightTaken]); @@ -341,5 +369,6 @@ export function usePhotoCaptureSightState({ setLastPictureTakenUri, retryLoadingInspection, retakeSight, + isInspectionCompliant, }); } diff --git a/packages/inspection-capture-web/src/components/HUDOverlay/HUDOverlay.styles.ts b/packages/inspection-capture-web/src/components/HUDOverlay/HUDOverlay.styles.ts index c0852c5d3..9c7d18c4c 100644 --- a/packages/inspection-capture-web/src/components/HUDOverlay/HUDOverlay.styles.ts +++ b/packages/inspection-capture-web/src/components/HUDOverlay/HUDOverlay.styles.ts @@ -2,7 +2,7 @@ import { Styles } from '@monkvision/types'; export const styles: Styles = { overlay: { - position: 'absolute', + position: 'fixed', top: 0, left: 0, width: '100%', diff --git a/packages/inspection-capture-web/src/hooks/useStartTasksOnComplete.ts b/packages/inspection-capture-web/src/hooks/useStartTasksOnComplete.ts index cfc33ba13..0b162182a 100644 --- a/packages/inspection-capture-web/src/hooks/useStartTasksOnComplete.ts +++ b/packages/inspection-capture-web/src/hooks/useStartTasksOnComplete.ts @@ -56,7 +56,11 @@ function getTasksToStart({ } }); } - return tasks.filter((task) => !TASKS_NOT_TO_START.includes(task)); + return tasks.filter( + (task) => + !TASKS_NOT_TO_START.includes(task) && + !(task === TaskName.COMPLIANCES && tasks.includes(TaskName.DAMAGE_DETECTION)), + ); } /** @@ -81,8 +85,8 @@ export function useStartTasksOnComplete({ } const names = getTasksToStart({ sights, additionalTasks, tasksBySight, startTasksOnComplete }); - loading.start(); try { + loading.start(); await startInspectionTasks({ inspectionId, names }); loading.onSuccess(); } catch (err) { diff --git a/packages/inspection-capture-web/test/PhotoCapture/PhotoCapture.test.tsx b/packages/inspection-capture-web/test/PhotoCapture/PhotoCapture.test.tsx index 7b4e61467..e4cb63836 100644 --- a/packages/inspection-capture-web/test/PhotoCapture/PhotoCapture.test.tsx +++ b/packages/inspection-capture-web/test/PhotoCapture/PhotoCapture.test.tsx @@ -11,16 +11,16 @@ import { VehicleType, } from '@monkvision/types'; import { Camera } from '@monkvision/camera-web'; -import { useI18nSync, useLoadingState, usePreventExit } from '@monkvision/common'; +import { useI18nSync, useLoadingState } from '@monkvision/common'; import { BackdropDialog, InspectionGallery } from '@monkvision/common-ui-web'; -import { useMonitoring } from '@monkvision/monitoring'; import { expectPropsOnChildMock } from '@monkvision/test-utils'; -import { act, render, waitFor } from '@testing-library/react'; +import { act, render } from '@testing-library/react'; import { PhotoCapture, PhotoCaptureHUD, PhotoCaptureProps } from '../../src'; import { usePhotoCaptureSightState, usePhotoCaptureTutorial, usePhotoCaptureSightGuidelines, + useInspectionComplete, } from '../../src/PhotoCapture/hooks'; import { useStartTasksOnComplete, @@ -55,6 +55,9 @@ jest.mock('../../src/PhotoCapture/hooks', () => ({ usePhotoCaptureSightGuidelines: jest.fn(() => ({ showSightGuidelines: true, })), + useInspectionComplete: jest.fn(() => ({ + handleInspectionCompleted: jest.fn(), + })), })); jest.mock('../../src/hooks', () => ({ @@ -211,6 +214,8 @@ describe('PhotoCapture component', () => { loading, onLastSightTaken: expect.any(Function), tasksBySight: props.tasksBySight, + startTasksOnComplete: props.startTasksOnComplete, + onComplete: props.onComplete, complianceOptions: { enableCompliance: props.enableCompliance, enableCompliancePerSight: props.enableCompliancePerSight, @@ -289,6 +294,27 @@ describe('PhotoCapture component', () => { unmount(); }); + it('should pass the proper params to the useInspectionCompletehook', () => { + const props = { ...createProps(), tasksBySight: { test: [TaskName.PRICING] } }; + const { unmount } = render(); + + expect(useStartTasksOnComplete).toHaveBeenCalled(); + const startTasks = (useStartTasksOnComplete as jest.Mock).mock.results[0].value; + expect(usePhotoCaptureSightState).toHaveBeenCalled(); + const sightState = (usePhotoCaptureSightState as jest.Mock).mock.results[0].value; + expect(useLoadingState).toHaveBeenCalled(); + const loading = (useLoadingState as jest.Mock).mock.results[0].value; + expect(useInspectionComplete).toHaveBeenCalledWith({ + startTasksOnComplete: props.startTasksOnComplete, + startTasks, + sightState, + loading, + onComplete: props.onComplete, + }); + + unmount(); + }); + it('should display a Camera with the config obtained from the useAdaptiveCameraConfig', () => { const props = createProps(); const { unmount } = render(); @@ -417,55 +443,6 @@ describe('PhotoCapture component', () => { unmount(); }); - it('should call start tasks on gallery validate', async () => { - const startTasksMock = jest.fn(() => Promise.resolve()); - (useStartTasksOnComplete as jest.Mock).mockImplementation(() => startTasksMock); - const props = createProps(); - const { unmount } = render(); - - expect(InspectionGallery).not.toHaveBeenCalled(); - expectPropsOnChildMock(Camera, { - hudProps: expect.objectContaining({ onOpenGallery: expect.any(Function) }), - }); - const { onOpenGallery } = (Camera as unknown as jest.Mock).mock.calls[0][0].hudProps; - expect(InspectionGallery).not.toHaveBeenCalled(); - act(() => onOpenGallery()); - expectPropsOnChildMock(InspectionGallery, { - onValidate: expect.any(Function), - }); - const { onValidate } = (InspectionGallery as unknown as jest.Mock).mock.calls[0][0]; - - expect(useMonitoring).toHaveBeenCalled(); - const handleErrorMock = (useMonitoring as jest.Mock).mock.results[0].value.handleError; - expect(useLoadingState).toHaveBeenCalled(); - const loadingMock = (useLoadingState as jest.Mock).mock.results[0].value; - - expect(startTasksMock).not.toHaveBeenCalled(); - expect(props.onComplete).not.toHaveBeenCalled(); - onValidate(); - - await waitFor(() => { - expect(startTasksMock).toHaveBeenCalled(); - expect(props.onComplete).toHaveBeenCalled(); - expect(loadingMock.onError).not.toHaveBeenCalled(); - expect(handleErrorMock).not.toHaveBeenCalled(); - }); - - startTasksMock.mockClear(); - (props.onComplete as jest.Mock).mockClear(); - const err = 'hello'; - startTasksMock.mockImplementation(() => Promise.reject(err)); - onValidate(); - - await waitFor(() => { - expect(startTasksMock).toHaveBeenCalled(); - expect(props.onComplete).not.toHaveBeenCalled(); - }); - - unmount(); - (useStartTasksOnComplete as jest.Mock).mockClear(); - }); - it('should pass the proper params to the BackdropDialog component', () => { const props = createProps(); const { unmount } = render(); @@ -489,11 +466,4 @@ describe('PhotoCapture component', () => { unmount(); }); - - it('should ask the user for confirmation before exit', () => { - const props = createProps(); - const { unmount } = render(); - expect(usePreventExit).toHaveBeenCalled(); - unmount(); - }); }); diff --git a/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.test.tsx b/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.test.tsx index 19ffaeb24..863384b0c 100644 --- a/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.test.tsx +++ b/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUD.test.tsx @@ -94,7 +94,6 @@ describe('PhotoCaptureHUD component', () => { onAddDamage: props.onAddDamage, onCancelAddDamage: props.onCancelAddDamage, onSelectSight: props.onSelectSight, - isLoading: props.loading.isLoading || props.handle.isLoading, error: props.loading.error ?? props.handle.error, previewDimensions: props.handle.previewDimensions, images: props.images, diff --git a/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements.test.tsx b/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements.test.tsx index dbd196be7..49592eaf9 100644 --- a/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements.test.tsx +++ b/packages/inspection-capture-web/test/PhotoCapture/PhotoCaptureHUD/PhotoCaptureHUDElements.test.tsx @@ -34,7 +34,6 @@ function createProps(): PhotoCaptureHUDElementsProps { onSelectSight: jest.fn(), onRetakeSight: jest.fn(), previewDimensions: { height: 1234, width: 45678 }, - isLoading: false, error: null, images: [{ sightId: 'test-sight-1', status: ImageStatus.NOT_COMPLIANT }] as Image[], tutorialStep: null, @@ -50,16 +49,6 @@ describe('PhotoCaptureHUDElements component', () => { jest.clearAllMocks(); }); - it('should return null if the capture is loading', () => { - const props = createProps(); - props.isLoading = true; - const { container, unmount } = render(); - - expect(container).toBeEmptyDOMElement(); - - unmount(); - }); - it('should return null if the capture is in error', () => { const props = createProps(); props.error = true; diff --git a/packages/inspection-capture-web/test/PhotoCapture/hooks/usePhotoCaptureSightState.test.ts b/packages/inspection-capture-web/test/PhotoCapture/hooks/usePhotoCaptureSightState.test.ts index 762caf340..d24e3b302 100644 --- a/packages/inspection-capture-web/test/PhotoCapture/hooks/usePhotoCaptureSightState.test.ts +++ b/packages/inspection-capture-web/test/PhotoCapture/hooks/usePhotoCaptureSightState.test.ts @@ -48,6 +48,8 @@ function createParams(): PhotoCaptureSightsParams { useLiveCompliance: true, }, setIsInitialInspectionFetched: jest.fn(), + onComplete: jest.fn(), + startTasksOnComplete: false, }; } diff --git a/packages/inspection-capture-web/test/components/HUDOverlay.test.tsx b/packages/inspection-capture-web/test/components/HUDOverlay.test.tsx index 8c5edd42b..dca18f8c3 100644 --- a/packages/inspection-capture-web/test/components/HUDOverlay.test.tsx +++ b/packages/inspection-capture-web/test/components/HUDOverlay.test.tsx @@ -60,7 +60,7 @@ describe('HUDOverlay component', () => { const { unmount } = render(); expect(screen.getByTestId(OVERLAY_TEST_ID)).toHaveStyle({ - position: 'absolute', + position: 'fixed', top: 0, left: 0, width: '100%', diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index 15af77c59..d5f90dda6 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -114,7 +114,7 @@ export type SharedCaptureAppConfig = CameraConfig & { * Value indicating if tasks should be started at the end of the inspection : * - If not provided or if value is set to `false`, no tasks will be started. * - If set to `true`, for photo capture apps : the tasks described by the `tasksBySight` param (or, if not provided, - * the default tasks of each sight) will be started. + * the default tasks of each sight) will be started, but only if all images are compliant. * - If set to `true`, for video capture apps : the default tasks of each sight (and also optionally the ones * described by the `additionalTasks` param) will be started. * - If an array of tasks is provided, the tasks started will be the ones contained in the array.