Skip to content

Commit

Permalink
Added sight guidelines
Browse files Browse the repository at this point in the history
  • Loading branch information
dlymonkai committed Jul 3, 2024
1 parent 7d9655a commit 9af8a3f
Show file tree
Hide file tree
Showing 25 changed files with 334 additions and 80 deletions.
19 changes: 18 additions & 1 deletion apps/demo-app/src/local-config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"allowSkipRetake": true,
"enableAddDamage": true,
"enableAddDamage": false,
"enableSightGuideline": true,
"allowVehicleTypeSelection": true,
"allowManualLogin": true,
"fetchFromSearchParams": true,
Expand Down Expand Up @@ -183,6 +184,22 @@
"ff150-7nvlys8r"
]
},
"sightGuidelines": [
{
"en": "Stand centred in front of the vehicle",
"fr": "Placez-vous centré devant le véhicule",
"de": "Stellen Sie sich zentriert vor das Fahrzeug",
"nl": "Plaats jezelf in het midden voor het voertuig",
"sightIds": ["jgc21-QIvfeg0X", "ff150-zXbg0l3z"]
},
{
"en": "Stand centred in front of the vehicle, aligned with the front grille. Center the vehicle in the frame, ensuring the entire hood, windshield and side mirrors are visible. Include the top of the vehicle in the shot.",
"fr": "Placez-vous au centré devant le véhicule, aligné avec la calandre avant. Centrez le véhicule dans le cadre, en veillant à ce que l'ensemble du capot, du pare-brise et des rétroviseurs soient visibles. Incluez le haut du véhicule dans la prise de vue.",
"de": "Stellen Sie sich zentriert vor das Fahrzeug, ausgerichtet an der Frontstoßstange. Zentrieren Sie das Fahrzeug im Rahmen, achten Sie darauf, dass die gesamte Motorhaube, die Windschutzscheibe und die Seitenspiegel sichtbar sind. Nehmen Sie die Oberseite des Fahrzeugs in den Schuss auf.",
"nl": "Plaats jezelf in het midden voor het voertuig, uitgelijnd met de voorgril. Centreren Sie het voertuig in de beeldframe, zorg ervoor dat de hele motorkap, de voorruit en de zijspiegels zichtbaar zijn. Neem de bovenkant van het voertuig op in de opname.",
"sightIds": ["jgc21-KyUUVU2P", "ffocus18-XlfgjQb9 ", "ff150-3he9UOwy"]
}
],
"requiredApiPermissions": [
"monk_core_api:compliances",
"monk_core_api:damage_detection",
Expand Down
1 change: 1 addition & 0 deletions configs/test-utils/src/__mocks__/@monkvision/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,5 @@ export = {
useSearchParams: jest.fn(() => ({ get: jest.fn(() => null) })),
useObjectMemo: jest.fn((obj) => obj),
usePreventExit: jest.fn(),
getLanguage: jest.fn(),
};
10 changes: 10 additions & 0 deletions documentation/src/utils/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ export const ComplianceOptionsSchema = z.object({
.refine(validateSightIds, getInvalidSightIdsMessage),
});

export const SightGuidelineSchema = z.object({
sightIds: z.array(z.string()),
en: z.string(),
fr: z.string(),
de: z.string(),
nl: z.string(),
});

export const AccentColorVariantsSchema = z.object({
xdark: z.string(),
dark: z.string(),
Expand Down Expand Up @@ -220,6 +228,8 @@ export const LiveConfigSchema = z
useAdaptiveImageQuality: z.boolean().optional(),
allowSkipRetake: z.boolean().optional(),
enableAddDamage: z.boolean().optional(),
enableSightGuideline: z.boolean().optional(),
sightGuidelines: z.array(SightGuidelineSchema),
defaultVehicleType: z.nativeEnum(VehicleType),
allowManualLogin: z.boolean(),
allowVehicleTypeSelection: z.boolean(),
Expand Down
14 changes: 8 additions & 6 deletions packages/common-ui-web/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ export const Button = forwardRef<HTMLButtonElement, PropsWithChildren<ButtonProp
() => (
<>
{icon && (
<Icon
icon={icon}
size={iconStyle.size}
primaryColor={iconStyle.color}
style={iconStyle.style}
/>
<div style={{ width: iconStyle.size, height: iconStyle.size, ...iconStyle.style }}>
<Icon
icon={icon}
primaryColor={iconStyle.color}
size={iconStyle.size}
style={iconStyle.style}
/>
</div>
)}
{children}
</>
Expand Down
19 changes: 14 additions & 5 deletions packages/common-ui-web/src/components/Button/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ export function useButtonStyle(params: MonkButtonStyleParams): MonkButtonStyle {
const contentSize =
params.size === 'normal' ? BUTTON_CONTENT_SIZE_NORMAL : BUTTON_CONTENT_SIZE_SMALL;

const iconStyle = {
...styles['icon'],
...(params.size === 'small' ? styles['iconSmall'] : {}),
...(!params.hasChildren ? styles['iconOnly'] : {}),
};

return {
style: {
...styles['button'],
Expand All @@ -172,14 +178,17 @@ export function useButtonStyle(params: MonkButtonStyleParams): MonkButtonStyle {
backgroundColor,
},
iconStyle: {
style: {
...styles['icon'],
...(params.size === 'small' ? styles['iconSmall'] : {}),
...(!params.hasChildren ? styles['iconOnly'] : {}),
},
style: iconStyle,
color: foregroundColor,
size: contentSize,
},
iconContainerStyle: {
style: {
width: contentSize,
height: contentSize,
...iconStyle,
},
},
spinnerStyle: {
style: {
top: `calc(50% - ${contentSize / 2}px)`,
Expand Down
6 changes: 3 additions & 3 deletions packages/common/src/hooks/useObjectTranslation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MonkLanguage, TranslationObject } from '@monkvision/types';
import { TranslationObject } from '@monkvision/types';
import { useTranslation } from 'react-i18next';
import { useCallback } from 'react';
import { getLanguage } from '../i18n';

/**
* The result of the useObjectTranslation. It contains a function which takes a LabelTranslation object and return the
Expand All @@ -20,8 +21,7 @@ export function useObjectTranslation(): UseObjectTranslationResult {
const { i18n } = useTranslation();
const tObj = useCallback(
(obj: TranslationObject) => {
const lang = i18n.language.slice(0, 2) as MonkLanguage;
return obj[lang] ?? 'translation-not-found';
return obj[getLanguage(i18n.language)] ?? 'translation-not-found';
},
[i18n.language],
);
Expand Down
15 changes: 14 additions & 1 deletion packages/common/src/i18n/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
useEffect,
} from 'react';
import { I18nextProvider, initReactI18next, useTranslation } from 'react-i18next';
import { monkLanguages } from '@monkvision/types';
import { MonkLanguage, monkLanguages } from '@monkvision/types';

/**
* This custom hook automatically updates the current i18n instance's language with the given language if is it not null
Expand Down Expand Up @@ -88,3 +88,16 @@ export function i18nWrap<T, P>(
</I18nextProvider>
));
}

/**
* This function retrieves the language prefix from a given language string.
* If the prefix is not found in the list of supported languages (monkLanguages in Types package), defaults to 'en'.
*
* @param language - The full language string (e.g., 'en-US', 'fr-CA').
* @returns The language prefix if it is supported; otherwise, 'en'.
*
*/
export function getLanguage(language: string): MonkLanguage {
const languagePrefix = language.slice(0, 2) as MonkLanguage;
return monkLanguages.includes(languagePrefix) ? languagePrefix : 'en';
}
2 changes: 2 additions & 0 deletions packages/inspection-capture-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,5 @@ export function MonkPhotoCapturePage({ authToken }) {
| customComplianceThresholds | `CustomComplianceThresholds` | Custom thresholds that can be used to modify the strictness of the compliance for certain compliance issues. | | |
| customComplianceThresholdsPerSight | `Record<string, CustomComplianceThresholds>` | A map associating Sight IDs to custom compliance thresholds. | | |
| validateButtonLabel | `string` | Custom label for validate button in gallery view. | | |
| enableSightGuideline | `boolean` | Boolean indicating whether the sight guideline feature is enabled. If disabled, the guideline text will be hidden. | | `true` |
| sightGuidelines | `sightGuideline[]` | A collection of sight guidelines in different language with a list of sightIds associate to it. | | |
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export interface PhotoCaptureProps
| 'enforceOrientation'
| 'allowSkipRetake'
| 'enableAddDamage'
| 'sightGuidelines'
| 'enableSightGuidelines'
>,
Partial<CompressionOptions>,
Partial<ComplianceOptions> {
Expand Down Expand Up @@ -122,6 +124,8 @@ export function PhotoCapture({
useLiveCompliance = false,
allowSkipRetake = false,
enableAddDamage = true,
sightGuidelines,
enableSightGuidelines = true,
useAdaptiveImageQuality = true,
lang,
enforceOrientation,
Expand Down Expand Up @@ -249,6 +253,8 @@ export function PhotoCapture({
showCloseButton,
images,
enableAddDamage,
sightGuidelines,
enableSightGuidelines,
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useMemo, useState } from 'react';
import { Image, ImageStatus, Sight } from '@monkvision/types';
import { CaptureAppConfig, Image, ImageStatus, Sight } from '@monkvision/types';
import { useTranslation } from 'react-i18next';
import { BackdropDialog } from '@monkvision/common-ui-web';
import { CameraHUDProps } from '@monkvision/camera-web';
Expand All @@ -14,7 +14,9 @@ import { PhotoCaptureHUDElements } from './PhotoCaptureHUDElements';
/**
* Props of the PhotoCaptureHUD component.
*/
export interface PhotoCaptureHUDProps extends CameraHUDProps {
export interface PhotoCaptureHUDProps
extends CameraHUDProps,
Pick<CaptureAppConfig, 'enableSightGuidelines' | 'sightGuidelines' | 'enableAddDamage'> {
/**
* The inspection ID.
*/
Expand Down Expand Up @@ -82,12 +84,6 @@ export interface PhotoCaptureHUDProps extends CameraHUDProps {
* The current images taken by the user (ignoring retaken pictures etc.).
*/
images: Image[];
/**
* Boolean indicating if `Add Damage` feature should be enabled or not. If disabled, the `Add Damage` button will be hidden.
*
* @default true
*/
enableAddDamage?: boolean;
}

/**
Expand Down Expand Up @@ -115,6 +111,8 @@ export function PhotoCaptureHUD({
cameraPreview,
images,
enableAddDamage,
sightGuidelines,
enableSightGuidelines,
}: PhotoCaptureHUDProps) {
const { t } = useTranslation();
const [showCloseModal, setShowCloseModal] = useState(false);
Expand Down Expand Up @@ -154,6 +152,8 @@ export function PhotoCaptureHUD({
previewDimensions={handle.previewDimensions}
images={images}
enableAddDamage={enableAddDamage}
sightGuidelines={sightGuidelines}
enableSightGuidelines={enableSightGuidelines}
/>
</div>
<PhotoCaptureHUDButtons
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export const styles: Styles = {
justifyContent: 'space-evenly',
flexDirection: 'column',
padding: '30px 40px',
zIndex: '9',
backgroundColor: '#00000080',
position: 'absolute',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Image, PixelDimensions, Sight } from '@monkvision/types';
import { CaptureAppConfig, Image, PixelDimensions, Sight } from '@monkvision/types';
import { PhotoCaptureMode } from '../../hooks';
import { PhotoCaptureHUDElementsSight } from '../PhotoCaptureHUDElementsSight';
import { PhotoCaptureHUDElementsAddDamage1stShot } from '../PhotoCaptureHUDElementsAddDamage1stShot';
Expand All @@ -7,7 +7,8 @@ import { PhotoCaptureHUDElementsAddDamage2ndShot } from '../PhotoCaptureHUDEleme
/**
* Props of the PhotoCaptureHUDElements component.
*/
export interface PhotoCaptureHUDElementsProps {
export interface PhotoCaptureHUDElementsProps
extends Pick<CaptureAppConfig, 'enableSightGuidelines' | 'sightGuidelines' | 'enableAddDamage'> {
/**
* The currently selected sight in the PhotoCapture component : the sight that the user needs to capture.
*/
Expand Down Expand Up @@ -56,12 +57,6 @@ export interface PhotoCaptureHUDElementsProps {
* The current images taken by the user (ignoring retaken pictures etc.).
*/
images: Image[];
/**
* Boolean indicating if `Add Damage` feature should be enabled or not. If disabled, the `Add Damage` button will be hidden.
*
* @default true
*/
enableAddDamage?: boolean;
}

/**
Expand All @@ -83,6 +78,8 @@ export function PhotoCaptureHUDElements(params: PhotoCaptureHUDElementsProps) {
previewDimensions={params.previewDimensions}
images={params.images}
enableAddDamage={params.enableAddDamage}
sightGuidelines={params.sightGuidelines}
enableSightGuidelines={params.enableSightGuidelines}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Button } from '@monkvision/common-ui-web';
import { CSSProperties } from 'react';
import { useTranslation } from 'react-i18next';
import { usePhotoCaptureHUDButtonBackground } from '../../hooks';

Expand All @@ -19,10 +18,6 @@ export interface AddDamageButtonProps {
enableAddDamage?: boolean;
}

function getButtonStyle(enableAddDamage?: boolean): CSSProperties {
return { visibility: enableAddDamage ? 'visible' : 'hidden' };
}

/**
* Custom button displayed in the PhotoCapture Camera HUD that allows user to enter add damage mode.
*/
Expand All @@ -31,15 +26,17 @@ export function AddDamageButton({ onAddDamage, enableAddDamage }: AddDamageButto
const primaryColor = usePhotoCaptureHUDButtonBackground();

return (
<Button
icon='add'
style={getButtonStyle(enableAddDamage)}
disabled={!enableAddDamage}
onClick={onAddDamage}
data-testid='monk-test-btn'
primaryColor={primaryColor}
>
{t('photo.hud.sight.addDamageBtn')}
</Button>
<>
{enableAddDamage && (
<Button
icon='add'
onClick={onAddDamage}
data-testid='monk-test-btn'
primaryColor={primaryColor}
>
{t('photo.hud.sight.addDamageBtn')}
</Button>
)}
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export const styles: Styles = {
top: {
display: 'flex',
alignSelf: 'stretch',
flexDirection: 'row',
alignItems: 'start',
justifyContent: 'end',
justifyContent: 'space-between',
gap: 10,
margin: 10,
},
bottom: {
Expand All @@ -36,7 +36,4 @@ export const styles: Styles = {
alignItems: 'center',
zIndex: 9,
},
overlay: {
zIndex: 9,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AddDamageButton } from './AddDamageButton';
import { PhotoCaptureHUDElementsSightProps, usePhotoCaptureHUDSightPreviewStyle } from './hooks';
import { PhotoCaptureHUDCounter } from '../PhotoCaptureHUDCounter';
import { PhotoCaptureMode } from '../../hooks';
import { SightGuideline } from './SightGuideline';

/**
* Component implementing an HUD displayed on top of the Camera preview during the PhotoCapture process when the current
Expand All @@ -20,14 +21,22 @@ export function PhotoCaptureHUDElementsSight({
previewDimensions,
images,
enableAddDamage,
sightGuidelines,
enableSightGuidelines,
}: PhotoCaptureHUDElementsSightProps) {
const style = usePhotoCaptureHUDSightPreviewStyle({ previewDimensions });

return (
<div style={styles['container']}>
{previewDimensions && <SightOverlay style={style.overlay} sight={selectedSight} />}
{previewDimensions && <SightOverlay sight={selectedSight} />}
<div style={style.elementsContainer}>
<div style={style.top}>
<SightGuideline
sightId={selectedSight.id}
sightGuidelines={sightGuidelines}
enableSightGuidelines={enableSightGuidelines}
enableAddDamage={enableAddDamage}
/>
<AddDamageButton onAddDamage={onAddDamage} enableAddDamage={enableAddDamage} />
</div>
<div style={style.bottom}>
Expand Down
Loading

0 comments on commit 9af8a3f

Please sign in to comment.