Skip to content

Commit

Permalink
Added Sight guidelines EPHEMERAL option
Browse files Browse the repository at this point in the history
  • Loading branch information
dlymonkai committed Jan 30, 2025
1 parent 6426efb commit 742302e
Show file tree
Hide file tree
Showing 26 changed files with 435 additions and 90 deletions.
2 changes: 1 addition & 1 deletion apps/demo-app/src/local-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"workflow": "photo",
"allowSkipRetake": true,
"addDamage": "part_select",
"enableSightGuidelines": true,
"enableSightGuidelines": "ephemeral",
"allowVehicleTypeSelection": true,
"allowManualLogin": true,
"fetchFromSearchParams": true,
Expand Down
2 changes: 1 addition & 1 deletion documentation/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ The following table lists the available configuration options in the `PhotoCaptu
| allowSkipRetake | `boolean` | If compliance is enabled, this prop indicate if the user is allowed to skip the retaking process if some pictures are not compliant. | | `false` |
| addDamage | `AddDamage` | Options for Add Damage. If disabled, the `Add Damage` button will be hidden. | | `AddDamage.PART_SELECT` |
| sightGuidelines | `sightGuideline[]` | A collection of sight guidelines in different language with a list of sightIds associate to it. | | |
| enableSightGuideline | `boolean` | Boolean indicating whether the sight guideline feature is enabled. If disabled, the guideline text will be hidden. | | `true` |
| enableSightGuidelines | `PhotoCaptureSightGuidelinesOption` | Option for displaying the Sight guidelines. If disabled, the guideline text will be hidden. | | `PhotoCaptureSightGuidelines.EPHEMERAL` |
| defaultVehicleType | `VehicleType` | Default vehicle type to use if no vehicle type has been specified. | ✔️ | |
| allowVehicleTypeSelection | `boolean` | Indicates if manual vehicle type selection should be enabled if the vehicle type is not defined. | ✔️ | |
| enableTutorial | `PhotoCaptureTutorialOption` | Options for displaying the photo capture tutorial. | | `PhotoCaptureTutorialOption.FIRST_TIME_ONLY` |
Expand Down
3 changes: 2 additions & 1 deletion documentation/src/utils/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
DeviceOrientation,
MileageUnit,
MonkApiPermission,
PhotoCaptureSightGuidelinesOption,
PhotoCaptureTutorialOption,
SteeringWheelPosition,
TaskName,
Expand Down Expand Up @@ -309,7 +310,7 @@ export const LiveConfigSchema = z
useAdaptiveImageQuality: z.boolean().optional(),
allowSkipRetake: z.boolean().optional(),
addDamage: z.nativeEnum(AddDamage).optional(),
enableSightGuidelines: z.boolean().optional(),
enableSightGuidelines: z.nativeEnum(PhotoCaptureSightGuidelinesOption).optional(),
sightGuidelines: z.array(SightGuidelineSchema).optional(),
enableTutorial: z.nativeEnum(PhotoCaptureTutorialOption).optional(),
allowSkipTutorial: z.boolean().optional(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ComplianceOptions,
MonkPicture,
PhotoCaptureAppConfig,
PhotoCaptureSightGuidelinesOption,
PhotoCaptureTutorialOption,
Sight,
VehicleType,
Expand All @@ -37,6 +38,7 @@ import {
useComplianceAnalytics,
usePhotoCaptureSightState,
usePhotoCaptureTutorial,
usePhotoCaptureSightGuidelines,
} from './hooks';

/**
Expand Down Expand Up @@ -137,7 +139,7 @@ export function PhotoCapture({
enableTutorial = PhotoCaptureTutorialOption.FIRST_TIME_ONLY,
allowSkipTutorial = true,
enableSightTutorial = true,
enableSightGuidelines = true,
enableSightGuidelines = PhotoCaptureSightGuidelinesOption.EPHEMERAL,
useAdaptiveImageQuality = true,
lang,
enforceOrientation,
Expand Down Expand Up @@ -202,6 +204,9 @@ export function PhotoCapture({
enableSightGuidelines,
enableSightTutorial,
});
const { showSightGuidelines, handleDisableSightGuidelines } = usePhotoCaptureSightGuidelines({
enableSightGuidelines,
});
const {
isBadConnectionWarningDialogDisplayed,
closeBadConnectionWarningDialog,
Expand Down Expand Up @@ -277,10 +282,11 @@ export function PhotoCapture({
addDamage,
onValidateVehicleParts: addDamageHandle.handleValidateVehicleParts,
sightGuidelines,
enableSightGuidelines,
showSightGuidelines,
currentTutorialStep,
onNextTutorialStep: goToNextTutorialStep,
onCloseTutorial: closeTutorial,
onDisableSightGuidelines: handleDisableSightGuidelines,
allowSkipTutorial,
enforceOrientation,
vehicleType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export interface PhotoCaptureHUDProps
extends CameraHUDProps,
Pick<
PhotoCaptureAppConfig,
| 'enableSightGuidelines'
| 'sightGuidelines'
| 'addDamage'
| 'showCloseButton'
Expand Down Expand Up @@ -109,6 +108,10 @@ export interface PhotoCaptureHUDProps
* Callback called when the user clicks on the "Validate" button of the Add Damage mode.
*/
onValidateVehicleParts: () => void;
/**
* Callback called when the user clicks on both: 'disable' checkbox and 'okay' button.
*/
onDisableSightGuidelines: () => void;
/**
* Callback called when the user clicks on the close button. If this callback is not provided, the close button is not
* displayed.
Expand All @@ -122,6 +125,10 @@ export interface PhotoCaptureHUDProps
* The vehicle type of the inspection.
*/
vehicleType: VehicleType;
/**
* Boolean indicating whether the sight guidelines should be displayed.
*/
showSightGuidelines: boolean;
}

/**
Expand Down Expand Up @@ -153,13 +160,14 @@ export function PhotoCaptureHUD({
images,
addDamage,
sightGuidelines,
enableSightGuidelines,
showSightGuidelines,
currentTutorialStep,
allowSkipTutorial,
onNextTutorialStep,
onCloseTutorial,
enforceOrientation,
vehicleType,
onDisableSightGuidelines,
}: PhotoCaptureHUDProps) {
const { t } = useTranslation();
const [showCloseModal, setShowCloseModal] = useState(false);
Expand Down Expand Up @@ -203,9 +211,10 @@ export function PhotoCaptureHUD({
images={images}
addDamage={addDamage}
sightGuidelines={sightGuidelines}
enableSightGuidelines={enableSightGuidelines}
showSightGuidelines={showSightGuidelines}
tutorialStep={currentTutorialStep}
vehicleType={vehicleType}
onDisableSightGuidelines={onDisableSightGuidelines}
/>
</div>
{mode !== CaptureMode.ADD_DAMAGE_PART_SELECT && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { CaptureMode } from '../../../types';
* Props of the PhotoCaptureHUDElements component.
*/
export interface PhotoCaptureHUDElementsProps
extends Pick<PhotoCaptureAppConfig, 'enableSightGuidelines' | 'sightGuidelines' | 'addDamage'> {
extends Pick<PhotoCaptureAppConfig, 'sightGuidelines' | 'addDamage'> {
/**
* The currently selected sight in the PhotoCapture component : the sight that the user needs to capture.
*/
Expand Down Expand Up @@ -64,6 +64,10 @@ export interface PhotoCaptureHUDElementsProps
* Callback called when the user clicks on the "Validate" button of the Add Damage mode.
*/
onValidateVehicleParts: () => void;
/**
* Callback called when the user clicks on both: 'disable' checkbox and 'okay' button.
*/
onDisableSightGuidelines?: () => void;
/**
* The effective pixel dimensions of the Camera video stream on the screen.
*/
Expand All @@ -84,6 +88,10 @@ export interface PhotoCaptureHUDElementsProps
* The vehicle type of the inspection.
*/
vehicleType: VehicleType;
/**
* Boolean indicating whether the sight guidelines should be displayed.
*/
showSightGuidelines?: boolean;
}

/**
Expand All @@ -106,8 +114,9 @@ export function PhotoCaptureHUDElements(params: PhotoCaptureHUDElementsProps) {
images={params.images}
addDamage={params.addDamage}
sightGuidelines={params.sightGuidelines}
enableSightGuidelines={params.enableSightGuidelines}
showSightGuidelines={params.showSightGuidelines}
tutorialStep={params.tutorialStep}
onDisableSightGuidelines={params.onDisableSightGuidelines}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ export function PhotoCaptureHUDElementsSight({
onSelectedSight = () => {},
onRetakeSight = () => {},
onAddDamage = () => {},
onDisableSightGuidelines = () => {},
sightsTaken,
previewDimensions,
images,
addDamage,
sightGuidelines,
enableSightGuidelines,
showSightGuidelines,
tutorialStep,
}: PhotoCaptureHUDElementsSightProps) {
const style = usePhotoCaptureHUDSightPreviewStyle({ previewDimensions });
Expand All @@ -39,8 +40,9 @@ export function PhotoCaptureHUDElementsSight({
<SightGuideline
sightId={selectedSight.id}
sightGuidelines={sightGuidelines}
enableSightGuidelines={enableSightGuidelines}
disabled={!showSightGuidelines}
addDamage={addDamage}
onDisableSightGuidelines={onDisableSightGuidelines}
/>
<AddDamageButton onAddDamage={onAddDamage} addDamage={addDamage} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,29 @@ export const styles: Styles = {
width: `calc(98% - (${PHOTO_CAPTURE_HUD_BUTTONS_BAR_WIDTH * 4}px))`,
justifyContent: 'center',
},
button: {
textAlign: 'start',
guideline: {
display: 'flex',
flexDirection: 'column',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
borderRadius: '12px',
fontSize: 14,
flexDirection: 'row-reverse',
paddingRight: 0,
alignItems: 'start',
gap: 10,
justifyContent: 'start',
padding: '10px',
gap: '8px',
letterSpacing: '0.15px',
fontSize: '14',
},
buttonContainer: {
display: 'flex',
justifyContent: 'space-between',
padding: '0px 10px 0px',
},
checkbox: {
display: 'flex',
cursor: 'pointer',
gap: '5px',
},
button: {
all: 'unset',
cursor: 'pointer',
},
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { useEffect, useState } from 'react';
import { Button } from '@monkvision/common-ui-web';
import { AddDamage, PhotoCaptureAppConfig } from '@monkvision/types';
import { PhotoCaptureAppConfig } from '@monkvision/types';
import { useTranslation } from 'react-i18next';
import { getLanguage } from '@monkvision/common';
import { styles } from './SightGuideline.styles';
import { useColorBackground } from '../../../../hooks';
import { useSightGuidelineStyle } from './hooks';

/**
* Props of the SightGuideline component.
*/
export interface SightGuidelineProps
extends Pick<PhotoCaptureAppConfig, 'addDamage' | 'sightGuidelines' | 'enableSightGuidelines'> {
extends Pick<PhotoCaptureAppConfig, 'addDamage' | 'sightGuidelines'> {
/**
* The id of the sight.
*/
Expand All @@ -21,6 +20,16 @@ export interface SightGuidelineProps
* @default false
*/
enableDefaultMessage?: boolean;
/**
* Boolean indicating if the sight guidelines are enabled.
*
* @default true
*/
disabled?: boolean;
/**
* Callback called when the user clicks on both: 'disable' checkbox and 'okay' button.
*/
onDisableSightGuidelines?: () => void;
}

/**
Expand All @@ -29,15 +38,16 @@ export interface SightGuidelineProps
export function SightGuideline({
sightId,
sightGuidelines,
enableSightGuidelines,
addDamage,
enableDefaultMessage = false,
disabled = false,
onDisableSightGuidelines = () => {},
}: SightGuidelineProps) {
const [showGuideline, setShowGuideline] = useState(true);
const primaryColor = useColorBackground();
const { i18n, t } = useTranslation();
const [checked, setChecked] = useState(false);

const style = addDamage === AddDamage.DISABLED ? styles['containerWide'] : styles['container'];
const { i18n, t } = useTranslation();
const style = useSightGuidelineStyle({ addDamage });

const guidelineFound = sightGuidelines?.find((value) => value.sightIds.includes(sightId));

Expand All @@ -47,19 +57,46 @@ export function SightGuideline({

const guideline = guidelineFound ? guidelineFound[getLanguage(i18n.language)] : defaultMessage;

const handleShowSightGuidelines = () => {
if (checked) {
onDisableSightGuidelines();
}
setShowGuideline(false);
};

useEffect(() => setShowGuideline(true), [sightId]);

return (
<div style={style}>
{enableSightGuidelines && showGuideline && guideline && (
<Button
icon='close'
primaryColor={primaryColor}
style={styles['button']}
onClick={() => setShowGuideline(false)}
>
<div style={style.container} data-testid='container'>
{!disabled && showGuideline && guideline && (
<div style={style.guideline} data-testid='guideline'>
{guideline}
</Button>
<div style={styles['buttonContainer']}>
<div
style={styles['checkbox']}
role='checkbox'
aria-checked={checked}
tabIndex={0}
onClick={() => setChecked(!checked)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
setChecked(!checked);
}
}}
data-testid='checkbox-container'
>
<input type='checkbox' checked={checked} onChange={(e) => e.stopPropagation()} />
<span>{t('photo.hud.guidelines.disable')}</span>
</div>
<button
style={styles['button']}
onClick={handleShowSightGuidelines}
data-testid='button'
>
{t('photo.hud.guidelines.validate')}
</button>
</div>
</div>
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { AddDamage } from '@monkvision/types';
import { styles } from './SightGuideline.styles';
import { useColorBackground } from '../../../../hooks';

export interface SightGuidelineParams {
addDamage?: AddDamage;
}

export function useSightGuidelineStyle({ addDamage }: SightGuidelineParams) {
const backgroundColor = useColorBackground();

return {
container: addDamage === AddDamage.DISABLED ? styles['containerWide'] : styles['container'],
guideline: {
...styles['guideline'],
backgroundColor,
},
};
}
Loading

0 comments on commit 742302e

Please sign in to comment.