@monkvision/inspection-capture-web 5.1.7 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import { CameraConfig, ComplianceOptions, MonkPicture, PhotoCaptureAppConfig, Si
4
4
  /**
5
5
  * Props of the PhotoCapture component.
6
6
  */
7
- export interface PhotoCaptureProps extends Pick<PhotoCaptureAppConfig, keyof CameraConfig | 'maxUploadDurationWarning' | 'useAdaptiveImageQuality' | 'additionalTasks' | 'tasksBySight' | 'startTasksOnComplete' | 'showCloseButton' | 'enforceOrientation' | 'allowSkipRetake' | 'addDamage' | 'sightGuidelines' | 'enableSightGuidelines' | 'enableTutorial' | 'allowSkipTutorial' | 'enableSightTutorial' | 'sightTutorial'>, Partial<ComplianceOptions> {
7
+ export interface PhotoCaptureProps extends Pick<PhotoCaptureAppConfig, keyof CameraConfig | 'maxUploadDurationWarning' | 'useAdaptiveImageQuality' | 'additionalTasks' | 'tasksBySight' | 'startTasksOnComplete' | 'showCloseButton' | 'enforceOrientation' | 'allowSkipRetake' | 'addDamage' | 'sightGuidelines' | 'enableSightGuidelines' | 'enableTutorial' | 'allowSkipTutorial' | 'enableSightTutorial' | 'sightTutorial' | 'autoDeletePreviousSightImages'>, Partial<ComplianceOptions> {
8
8
  /**
9
9
  * The list of sights to take pictures of. The values in this array should be retreived from the `@monkvision/sights`
10
10
  * package.
@@ -48,4 +48,4 @@ export interface PhotoCaptureProps extends Pick<PhotoCaptureAppConfig, keyof Cam
48
48
  */
49
49
  validateButtonLabel?: string;
50
50
  }
51
- export declare function PhotoCapture({ sights, inspectionId, apiConfig, additionalTasks, tasksBySight, startTasksOnComplete, onClose, onComplete, onPictureTaken, maxUploadDurationWarning, showCloseButton, enableCompliance, enableCompliancePerSight, complianceIssues, complianceIssuesPerSight, customComplianceThresholds, customComplianceThresholdsPerSight, useLiveCompliance, allowSkipRetake, addDamage, sightGuidelines, enableTutorial, allowSkipTutorial, enableSightTutorial, sightTutorial, enableSightGuidelines, useAdaptiveImageQuality, lang, enforceOrientation, validateButtonLabel, vehicleType, ...initialCameraConfig }: PhotoCaptureProps): JSX.Element;
51
+ export declare function PhotoCapture({ sights, inspectionId, apiConfig, additionalTasks, tasksBySight, startTasksOnComplete, onClose, onComplete, onPictureTaken, maxUploadDurationWarning, showCloseButton, enableCompliance, enableCompliancePerSight, complianceIssues, complianceIssuesPerSight, customComplianceThresholds, customComplianceThresholdsPerSight, useLiveCompliance, allowSkipRetake, addDamage, sightGuidelines, enableTutorial, allowSkipTutorial, enableSightTutorial, sightTutorial, enableSightGuidelines, useAdaptiveImageQuality, lang, enforceOrientation, validateButtonLabel, vehicleType, autoDeletePreviousSightImages, ...initialCameraConfig }: PhotoCaptureProps): JSX.Element;
@@ -35,6 +35,7 @@ var PhotoCapture_styles_1 = require("./PhotoCapture.styles");
35
35
  var PhotoCaptureHUD_1 = require("./PhotoCaptureHUD");
36
36
  var hooks_1 = require("../hooks");
37
37
  var hooks_2 = require("./hooks");
38
+ var useImagesCleanup_1 = require("./hooks/useImagesCleanup");
38
39
  var PhotoCaptureScreen;
39
40
  (function (PhotoCaptureScreen) {
40
41
  PhotoCaptureScreen["CAMERA"] = "camera";
@@ -42,7 +43,7 @@ var PhotoCaptureScreen;
42
43
  })(PhotoCaptureScreen || (PhotoCaptureScreen = {}));
43
44
  // No ts-doc for this component : the component exported is PhotoCaptureHOC
44
45
  function PhotoCapture(_a) {
45
- var sights = _a.sights, inspectionId = _a.inspectionId, apiConfig = _a.apiConfig, additionalTasks = _a.additionalTasks, tasksBySight = _a.tasksBySight, _b = _a.startTasksOnComplete, startTasksOnComplete = _b === void 0 ? true : _b, onClose = _a.onClose, onComplete = _a.onComplete, onPictureTaken = _a.onPictureTaken, _c = _a.maxUploadDurationWarning, maxUploadDurationWarning = _c === void 0 ? 15000 : _c, _d = _a.showCloseButton, showCloseButton = _d === void 0 ? false : _d, _e = _a.enableCompliance, enableCompliance = _e === void 0 ? true : _e, enableCompliancePerSight = _a.enableCompliancePerSight, complianceIssues = _a.complianceIssues, complianceIssuesPerSight = _a.complianceIssuesPerSight, customComplianceThresholds = _a.customComplianceThresholds, customComplianceThresholdsPerSight = _a.customComplianceThresholdsPerSight, _f = _a.useLiveCompliance, useLiveCompliance = _f === void 0 ? false : _f, _g = _a.allowSkipRetake, allowSkipRetake = _g === void 0 ? false : _g, _h = _a.addDamage, addDamage = _h === void 0 ? types_1.AddDamage.PART_SELECT : _h, sightGuidelines = _a.sightGuidelines, _j = _a.enableTutorial, enableTutorial = _j === void 0 ? types_1.PhotoCaptureTutorialOption.FIRST_TIME_ONLY : _j, _k = _a.allowSkipTutorial, allowSkipTutorial = _k === void 0 ? true : _k, _l = _a.enableSightTutorial, enableSightTutorial = _l === void 0 ? types_1.PhotoCaptureSightTutorialOption.DISABLED : _l, sightTutorial = _a.sightTutorial, _m = _a.enableSightGuidelines, enableSightGuidelines = _m === void 0 ? types_1.PhotoCaptureSightGuidelinesOption.EPHEMERAL : _m, _o = _a.useAdaptiveImageQuality, useAdaptiveImageQuality = _o === void 0 ? true : _o, lang = _a.lang, enforceOrientation = _a.enforceOrientation, validateButtonLabel = _a.validateButtonLabel, _p = _a.vehicleType, vehicleType = _p === void 0 ? types_1.VehicleType.SEDAN : _p, initialCameraConfig = __rest(_a, ["sights", "inspectionId", "apiConfig", "additionalTasks", "tasksBySight", "startTasksOnComplete", "onClose", "onComplete", "onPictureTaken", "maxUploadDurationWarning", "showCloseButton", "enableCompliance", "enableCompliancePerSight", "complianceIssues", "complianceIssuesPerSight", "customComplianceThresholds", "customComplianceThresholdsPerSight", "useLiveCompliance", "allowSkipRetake", "addDamage", "sightGuidelines", "enableTutorial", "allowSkipTutorial", "enableSightTutorial", "sightTutorial", "enableSightGuidelines", "useAdaptiveImageQuality", "lang", "enforceOrientation", "validateButtonLabel", "vehicleType"]);
46
+ var sights = _a.sights, inspectionId = _a.inspectionId, apiConfig = _a.apiConfig, additionalTasks = _a.additionalTasks, tasksBySight = _a.tasksBySight, _b = _a.startTasksOnComplete, startTasksOnComplete = _b === void 0 ? true : _b, onClose = _a.onClose, onComplete = _a.onComplete, onPictureTaken = _a.onPictureTaken, _c = _a.maxUploadDurationWarning, maxUploadDurationWarning = _c === void 0 ? 15000 : _c, _d = _a.showCloseButton, showCloseButton = _d === void 0 ? false : _d, _e = _a.enableCompliance, enableCompliance = _e === void 0 ? true : _e, enableCompliancePerSight = _a.enableCompliancePerSight, complianceIssues = _a.complianceIssues, complianceIssuesPerSight = _a.complianceIssuesPerSight, customComplianceThresholds = _a.customComplianceThresholds, customComplianceThresholdsPerSight = _a.customComplianceThresholdsPerSight, _f = _a.useLiveCompliance, useLiveCompliance = _f === void 0 ? false : _f, _g = _a.allowSkipRetake, allowSkipRetake = _g === void 0 ? false : _g, _h = _a.addDamage, addDamage = _h === void 0 ? types_1.AddDamage.PART_SELECT : _h, sightGuidelines = _a.sightGuidelines, _j = _a.enableTutorial, enableTutorial = _j === void 0 ? types_1.PhotoCaptureTutorialOption.FIRST_TIME_ONLY : _j, _k = _a.allowSkipTutorial, allowSkipTutorial = _k === void 0 ? true : _k, _l = _a.enableSightTutorial, enableSightTutorial = _l === void 0 ? types_1.PhotoCaptureSightTutorialOption.DISABLED : _l, sightTutorial = _a.sightTutorial, _m = _a.enableSightGuidelines, enableSightGuidelines = _m === void 0 ? types_1.PhotoCaptureSightGuidelinesOption.EPHEMERAL : _m, _o = _a.useAdaptiveImageQuality, useAdaptiveImageQuality = _o === void 0 ? true : _o, lang = _a.lang, enforceOrientation = _a.enforceOrientation, validateButtonLabel = _a.validateButtonLabel, _p = _a.vehicleType, vehicleType = _p === void 0 ? types_1.VehicleType.SEDAN : _p, _q = _a.autoDeletePreviousSightImages, autoDeletePreviousSightImages = _q === void 0 ? true : _q, initialCameraConfig = __rest(_a, ["sights", "inspectionId", "apiConfig", "additionalTasks", "tasksBySight", "startTasksOnComplete", "onClose", "onComplete", "onPictureTaken", "maxUploadDurationWarning", "showCloseButton", "enableCompliance", "enableCompliancePerSight", "complianceIssues", "complianceIssuesPerSight", "customComplianceThresholds", "customComplianceThresholdsPerSight", "useLiveCompliance", "allowSkipRetake", "addDamage", "sightGuidelines", "enableTutorial", "allowSkipTutorial", "enableSightTutorial", "sightTutorial", "enableSightGuidelines", "useAdaptiveImageQuality", "lang", "enforceOrientation", "validateButtonLabel", "vehicleType", "autoDeletePreviousSightImages"]);
46
47
  (0, common_1.useI18nSync)(lang);
47
48
  var complianceOptions = (0, common_1.useObjectMemo)({
48
49
  enableCompliance: enableCompliance,
@@ -54,7 +55,7 @@ function PhotoCapture(_a) {
54
55
  customComplianceThresholdsPerSight: customComplianceThresholdsPerSight,
55
56
  });
56
57
  var t = (0, react_i18next_1.useTranslation)().t;
57
- var _q = (0, react_1.useState)(PhotoCaptureScreen.CAMERA), currentScreen = _q[0], setCurrentScreen = _q[1];
58
+ var _r = (0, react_1.useState)(PhotoCaptureScreen.CAMERA), currentScreen = _r[0], setCurrentScreen = _r[1];
58
59
  var analytics = (0, analytics_1.useAnalytics)();
59
60
  var loading = (0, common_1.useLoadingState)();
60
61
  var handleOpenGallery = function () {
@@ -67,10 +68,10 @@ function PhotoCapture(_a) {
67
68
  });
68
69
  (0, hooks_1.useTracking)({ inspectionId: inspectionId, authToken: apiConfig.authToken });
69
70
  var setIsInitialInspectionFetched = (0, hooks_2.useComplianceAnalytics)({ inspectionId: inspectionId, sights: sights }).setIsInitialInspectionFetched;
70
- var _r = (0, hooks_1.useAdaptiveCameraConfig)({
71
+ var _s = (0, hooks_1.useAdaptiveCameraConfig)({
71
72
  initialCameraConfig: initialCameraConfig,
72
73
  useAdaptiveImageQuality: useAdaptiveImageQuality,
73
- }), adaptiveCameraConfig = _r.adaptiveCameraConfig, adaptiveUploadEventHandlers = _r.uploadEventHandlers;
74
+ }), adaptiveCameraConfig = _s.adaptiveCameraConfig, adaptiveUploadEventHandlers = _s.uploadEventHandlers;
74
75
  var startTasks = (0, hooks_1.useStartTasksOnComplete)({
75
76
  inspectionId: inspectionId,
76
77
  apiConfig: apiConfig,
@@ -83,6 +84,12 @@ function PhotoCapture(_a) {
83
84
  var onLastSightTaken = function () {
84
85
  setCurrentScreen(PhotoCaptureScreen.GALLERY);
85
86
  };
87
+ var _t = (0, hooks_2.usePhotoCaptureTutorial)({
88
+ enableTutorial: enableTutorial,
89
+ enableSightGuidelines: enableSightGuidelines,
90
+ enableSightTutorial: enableSightTutorial,
91
+ }), currentTutorialStep = _t.currentTutorialStep, goToNextTutorialStep = _t.goToNextTutorialStep, closeTutorial = _t.closeTutorial;
92
+ var _u = (0, hooks_2.usePhotoCaptureSightTutorial)(), showSightTutorial = _u.showSightTutorial, toggleSightTutorial = _u.toggleSightTutorial;
86
93
  var sightState = (0, hooks_2.usePhotoCaptureSightState)({
87
94
  inspectionId: inspectionId,
88
95
  captureSights: sights,
@@ -92,23 +99,27 @@ function PhotoCapture(_a) {
92
99
  tasksBySight: tasksBySight,
93
100
  complianceOptions: complianceOptions,
94
101
  setIsInitialInspectionFetched: setIsInitialInspectionFetched,
102
+ toggleSightTutorial: toggleSightTutorial,
95
103
  });
96
- var _s = (0, hooks_2.usePhotoCaptureTutorial)({
97
- enableTutorial: enableTutorial,
104
+ var _v = (0, hooks_2.usePhotoCaptureSightGuidelines)({
98
105
  enableSightGuidelines: enableSightGuidelines,
99
- enableSightTutorial: enableSightTutorial,
100
- }), currentTutorialStep = _s.currentTutorialStep, goToNextTutorialStep = _s.goToNextTutorialStep, closeTutorial = _s.closeTutorial;
101
- var _t = (0, hooks_2.usePhotoCaptureSightTutorial)(), showSightTutorial = _t.showSightTutorial, toggleSightTutorial = _t.toggleSightTutorial;
102
- var _u = (0, hooks_2.usePhotoCaptureSightGuidelines)({
103
- enableSightGuidelines: enableSightGuidelines,
104
- }), showSightGuidelines = _u.showSightGuidelines, handleDisableSightGuidelines = _u.handleDisableSightGuidelines;
105
- var _v = (0, hooks_1.useBadConnectionWarning)({ maxUploadDurationWarning: maxUploadDurationWarning }), isBadConnectionWarningDialogDisplayed = _v.isBadConnectionWarningDialogDisplayed, closeBadConnectionWarningDialog = _v.closeBadConnectionWarningDialog, badConnectionWarningUploadEventHandlers = _v.uploadEventHandlers;
106
+ }), showSightGuidelines = _v.showSightGuidelines, handleDisableSightGuidelines = _v.handleDisableSightGuidelines;
107
+ var _w = (0, hooks_1.useBadConnectionWarning)({ maxUploadDurationWarning: maxUploadDurationWarning }), isBadConnectionWarningDialogDisplayed = _w.isBadConnectionWarningDialogDisplayed, closeBadConnectionWarningDialog = _w.closeBadConnectionWarningDialog, badConnectionWarningUploadEventHandlers = _w.uploadEventHandlers;
108
+ var cleanupEventHandlers = (0, useImagesCleanup_1.useImagesCleanup)({
109
+ inspectionId: inspectionId,
110
+ apiConfig: apiConfig,
111
+ autoDeletePreviousSightImages: autoDeletePreviousSightImages,
112
+ }).cleanupEventHandlers;
106
113
  var uploadQueue = (0, hooks_1.useUploadQueue)({
107
114
  inspectionId: inspectionId,
108
115
  apiConfig: apiConfig,
109
116
  additionalTasks: additionalTasks,
110
117
  complianceOptions: complianceOptions,
111
- eventHandlers: [adaptiveUploadEventHandlers, badConnectionWarningUploadEventHandlers],
118
+ eventHandlers: [
119
+ adaptiveUploadEventHandlers,
120
+ badConnectionWarningUploadEventHandlers,
121
+ cleanupEventHandlers,
122
+ ],
112
123
  });
113
124
  var images = (0, hooks_1.usePhotoCaptureImages)(inspectionId);
114
125
  var handlePictureTaken = (0, hooks_1.usePictureTaken)({
@@ -25,6 +25,7 @@ exports.styles = {
25
25
  gap: '8px',
26
26
  letterSpacing: '0.15px',
27
27
  fontSize: '14',
28
+ whiteSpace: 'pre-line',
28
29
  },
29
30
  buttonContainer: {
30
31
  display: 'flex',
@@ -4,3 +4,4 @@ export * from './usePhotoCaptureTutorial';
4
4
  export * from './usePhotoCaptureSightGuidelines';
5
5
  export * from './useInspectionComplete';
6
6
  export * from './usePhotoCaptureSightTutorial';
7
+ export * from './useImagesCleanup';
@@ -20,3 +20,4 @@ __exportStar(require("./usePhotoCaptureTutorial"), exports);
20
20
  __exportStar(require("./usePhotoCaptureSightGuidelines"), exports);
21
21
  __exportStar(require("./useInspectionComplete"), exports);
22
22
  __exportStar(require("./usePhotoCaptureSightTutorial"), exports);
23
+ __exportStar(require("./useImagesCleanup"), exports);
@@ -0,0 +1,35 @@
1
+ import { MonkApiConfig } from '@monkvision/network';
2
+ import { UploadEventHandlers } from '../../hooks/useUploadQueue';
3
+ /**
4
+ * Parameters accepted by the useImagesCleanup hook.
5
+ */
6
+ export interface ImagesCleanupParams {
7
+ /**
8
+ * The inspection ID.
9
+ */
10
+ inspectionId: string;
11
+ /**
12
+ * The api config used to communicate with the API.
13
+ */
14
+ apiConfig: MonkApiConfig;
15
+ /**
16
+ * Boolean indicating if previous images for a sight should be automatically deleted when a new image is taken.
17
+ *
18
+ * @default true
19
+ */
20
+ autoDeletePreviousSightImages: boolean;
21
+ }
22
+ /**
23
+ * Handle used to manage the images cleanup after a new one uploads.
24
+ */
25
+ export interface ImagesCleanupHandle {
26
+ /**
27
+ * A set of event handlers listening to upload events.
28
+ */
29
+ cleanupEventHandlers: UploadEventHandlers;
30
+ }
31
+ /**
32
+ * Custom hook used to cleanup sights' images of the inspection by deleting the old ones
33
+ * when a new image is added.
34
+ */
35
+ export declare function useImagesCleanup({ inspectionId, apiConfig, autoDeletePreviousSightImages, }: ImagesCleanupParams): ImagesCleanupHandle;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.useImagesCleanup = void 0;
13
+ var common_1 = require("@monkvision/common");
14
+ var network_1 = require("@monkvision/network");
15
+ var react_1 = require("react");
16
+ function extractOtherImagesToDelete(imagesBySight) {
17
+ var imagesToDelete = [];
18
+ Object.values(imagesBySight)
19
+ .filter(function (images) { return images.length > 1; })
20
+ .forEach(function (images) {
21
+ var sortedImages = images.sort(function (a, b) {
22
+ return b.createdAt && a.createdAt ? b.createdAt - a.createdAt : 0;
23
+ });
24
+ imagesToDelete.push.apply(imagesToDelete, sortedImages.slice(1));
25
+ });
26
+ return imagesToDelete;
27
+ }
28
+ function groupImagesBySightId(images, sightIdToSkip) {
29
+ return images.reduce(function (acc, image) {
30
+ if (!image.sightId || image.sightId === sightIdToSkip) {
31
+ return acc;
32
+ }
33
+ if (!acc[image.sightId]) {
34
+ acc[image.sightId] = [];
35
+ }
36
+ acc[image.sightId].push(image);
37
+ return acc;
38
+ }, {});
39
+ }
40
+ /**
41
+ * Custom hook used to cleanup sights' images of the inspection by deleting the old ones
42
+ * when a new image is added.
43
+ */
44
+ function useImagesCleanup(_a) {
45
+ var inspectionId = _a.inspectionId, apiConfig = _a.apiConfig, autoDeletePreviousSightImages = _a.autoDeletePreviousSightImages;
46
+ var deleteImage = (0, network_1.useMonkApi)(apiConfig).deleteImage;
47
+ var state = (0, common_1.useMonkState)().state;
48
+ var onUploadSuccess = (0, react_1.useCallback)(function (_a) {
49
+ var sightId = _a.sightId, imageId = _a.imageId;
50
+ if (!sightId || !autoDeletePreviousSightImages) {
51
+ return;
52
+ }
53
+ var otherImagesToDelete = extractOtherImagesToDelete(groupImagesBySightId(state.images, sightId));
54
+ var sightImagesToDelete = state.images.filter(function (image) {
55
+ return image.inspectionId === inspectionId && image.sightId === sightId && image.id !== imageId;
56
+ });
57
+ var imagesToDelete = __spreadArray(__spreadArray([], otherImagesToDelete, true), sightImagesToDelete, true);
58
+ if (imagesToDelete.length > 0) {
59
+ imagesToDelete.forEach(function (image) { return deleteImage({ imageId: image.id, id: inspectionId }); });
60
+ }
61
+ }, [state.images, inspectionId]);
62
+ return (0, common_1.useObjectMemo)({
63
+ cleanupEventHandlers: {
64
+ onUploadSuccess: onUploadSuccess,
65
+ },
66
+ });
67
+ }
68
+ exports.useImagesCleanup = useImagesCleanup;
@@ -88,9 +88,11 @@ export interface PhotoCaptureSightsParams {
88
88
  * sight will be used.
89
89
  */
90
90
  tasksBySight?: Record<string, TaskName[]>;
91
+ /** Callback called to show the tutorial when retaking a non Car Coverage compliant sight. */
92
+ toggleSightTutorial: () => void;
91
93
  }
92
94
  /**
93
95
  * Custom hook used to manage the state of the PhotoCapture sights. This state is automatically fetched from the API at
94
96
  * the start of the PhotoCapture process in order to allow users to start the inspection where they left it before.
95
97
  */
96
- export declare function usePhotoCaptureSightState({ inspectionId, captureSights, apiConfig, loading, onLastSightTaken, tasksBySight, setIsInitialInspectionFetched, complianceOptions, }: PhotoCaptureSightsParams): PhotoCaptureSightState;
98
+ export declare function usePhotoCaptureSightState({ inspectionId, captureSights, apiConfig, loading, onLastSightTaken, tasksBySight, setIsInitialInspectionFetched, complianceOptions, toggleSightTutorial, }: PhotoCaptureSightsParams): PhotoCaptureSightState;
@@ -77,7 +77,7 @@ function getNotCompliantSights(inspectionId, captureSights, entities, notComplia
77
77
  * the start of the PhotoCapture process in order to allow users to start the inspection where they left it before.
78
78
  */
79
79
  function usePhotoCaptureSightState(_a) {
80
- var inspectionId = _a.inspectionId, captureSights = _a.captureSights, apiConfig = _a.apiConfig, loading = _a.loading, onLastSightTaken = _a.onLastSightTaken, tasksBySight = _a.tasksBySight, setIsInitialInspectionFetched = _a.setIsInitialInspectionFetched, complianceOptions = _a.complianceOptions;
80
+ var inspectionId = _a.inspectionId, captureSights = _a.captureSights, apiConfig = _a.apiConfig, loading = _a.loading, onLastSightTaken = _a.onLastSightTaken, tasksBySight = _a.tasksBySight, setIsInitialInspectionFetched = _a.setIsInitialInspectionFetched, complianceOptions = _a.complianceOptions, toggleSightTutorial = _a.toggleSightTutorial;
81
81
  if (captureSights.length === 0) {
82
82
  throw new Error('Empty sight list given to the Monk PhotoCapture component.');
83
83
  }
@@ -186,7 +186,15 @@ function usePhotoCaptureSightState(_a) {
186
186
  if (sightToRetake) {
187
187
  setSelectedSight(sightToRetake);
188
188
  }
189
- }, [captureSights]);
189
+ var hasCarCoverageComplianceIssues = state.images.some(function (image) {
190
+ return (image.sightId === id &&
191
+ image.complianceIssues &&
192
+ image.complianceIssues.some(function (issue) { return types_1.CAR_COVERAGE_COMPLIANCE_ISSUES.includes(issue); }));
193
+ });
194
+ if (hasCarCoverageComplianceIssues) {
195
+ toggleSightTutorial();
196
+ }
197
+ }, [captureSights, state.images, toggleSightTutorial]);
190
198
  var selectSight = function (s) {
191
199
  var _a, _b;
192
200
  var sightsNotTaken = (_a = captureSights.filter(function (sight) { return !sightsTaken.includes(sight); })) !== null && _a !== void 0 ? _a : [];
@@ -38,8 +38,9 @@ function useAdaptiveCameraConfig(_a) {
38
38
  setMaxResolution(types_1.CameraResolution.QHD_2K);
39
39
  setIsImageUpscalingAllowed(false);
40
40
  };
41
- var onUploadSuccess = (0, react_1.useCallback)(function (durationMs) {
42
- if (durationMs > MAX_UPLOAD_DURATION_MS) {
41
+ var onUploadSuccess = (0, react_1.useCallback)(function (_a) {
42
+ var durationMs = _a.durationMs;
43
+ if (durationMs && durationMs > MAX_UPLOAD_DURATION_MS) {
43
44
  lowerMaxImageQuality();
44
45
  }
45
46
  }, []);
@@ -11,8 +11,10 @@ function useBadConnectionWarning(_a) {
11
11
  var _b = (0, react_1.useState)(false), isBadConnectionWarningDialogDisplayed = _b[0], setIsBadConnectionWarningDialogDisplayed = _b[1];
12
12
  var hadDialogBeenDisplayed = (0, react_1.useRef)(false);
13
13
  var closeBadConnectionWarningDialog = (0, react_1.useCallback)(function () { return setIsBadConnectionWarningDialogDisplayed(false); }, []);
14
- var onUploadSuccess = (0, react_1.useCallback)(function (durationMs) {
15
- if (maxUploadDurationWarning >= 0 &&
14
+ var onUploadSuccess = (0, react_1.useCallback)(function (_a) {
15
+ var durationMs = _a.durationMs;
16
+ if (durationMs &&
17
+ maxUploadDurationWarning >= 0 &&
16
18
  durationMs > maxUploadDurationWarning &&
17
19
  !hadDialogBeenDisplayed.current) {
18
20
  setIsBadConnectionWarningDialogDisplayed(true);
@@ -2,16 +2,31 @@ import { Queue } from '@monkvision/common';
2
2
  import { MonkApiConfig } from '@monkvision/network';
3
3
  import { PhotoCaptureAppConfig, ComplianceOptions, MonkPicture, TaskName, VehiclePart } from '@monkvision/types';
4
4
  import { CaptureMode } from '../types';
5
+ /**
6
+ * Payload for the onUploadSuccess event handler.
7
+ */
8
+ export interface UploadSuccessPayload {
9
+ /**
10
+ * The total elapsed time in milliseconds between the start of the upload and the end of the upload.
11
+ */
12
+ durationMs?: number;
13
+ /**
14
+ * The sight ID associated with the uploaded picture, if applicable.
15
+ */
16
+ sightId?: string;
17
+ /**
18
+ * The ID of the uploaded image.
19
+ */
20
+ imageId?: string;
21
+ }
5
22
  /**
6
23
  * Type definition for upload event handlers.
7
24
  */
8
25
  export interface UploadEventHandlers {
9
26
  /**
10
27
  * Callback called when a picture upload successfully completes.
11
- *
12
- * @param durationMs The total elapsed time in milliseconds between the start of the upload and the end of the upload.
13
28
  */
14
- onUploadSuccess?: (durationMs: number) => void;
29
+ onUploadSuccess?: (payload: UploadSuccessPayload) => void;
15
30
  /**
16
31
  * Callback called when a picture upload fails because of a timeout.
17
32
  */
@@ -98,7 +98,7 @@ function useUploadQueue(_a) {
98
98
  var state = (0, common_1.useMonkState)().state;
99
99
  var wheelAnalysisCloseUp = (_b = state.tasks.find(function (task) { return task.name === types_1.TaskName.WHEEL_ANALYSIS && task.wheelAnalysisCloseUp; })) === null || _b === void 0 ? void 0 : _b.wheelAnalysisCloseUp;
100
100
  return (0, common_1.useQueue)(function (upload) { return __awaiter(_this, void 0, void 0, function () {
101
- var startTs, uploadDurationMs_1, err_1;
101
+ var startTs, result_1, uploadDurationMs_1, sightId_1, err_1;
102
102
  return __generator(this, function (_a) {
103
103
  switch (_a.label) {
104
104
  case 0:
@@ -111,9 +111,17 @@ function useUploadQueue(_a) {
111
111
  startTs = Date.now();
112
112
  return [4 /*yield*/, addImage(createAddImageOptions(upload, inspectionId, siblingIdRef.current, true, additionalTasks, complianceOptions, wheelAnalysisCloseUp))];
113
113
  case 2:
114
- _a.sent();
114
+ result_1 = _a.sent();
115
115
  uploadDurationMs_1 = Date.now() - startTs;
116
- eventHandlers === null || eventHandlers === void 0 ? void 0 : eventHandlers.forEach(function (handlers) { var _a; return (_a = handlers.onUploadSuccess) === null || _a === void 0 ? void 0 : _a.call(handlers, uploadDurationMs_1); });
116
+ sightId_1 = upload.mode === types_2.CaptureMode.SIGHT ? upload.sightId : undefined;
117
+ eventHandlers === null || eventHandlers === void 0 ? void 0 : eventHandlers.forEach(function (handlers) {
118
+ var _a, _b;
119
+ return (_a = handlers.onUploadSuccess) === null || _a === void 0 ? void 0 : _a.call(handlers, {
120
+ durationMs: uploadDurationMs_1,
121
+ sightId: sightId_1,
122
+ imageId: (_b = result_1 === null || result_1 === void 0 ? void 0 : result_1.image) === null || _b === void 0 ? void 0 : _b.id,
123
+ });
124
+ });
117
125
  return [3 /*break*/, 4];
118
126
  case 3:
119
127
  err_1 = _a.sent();
package/lib/i18n.js CHANGED
@@ -9,6 +9,7 @@ var en_json_1 = __importDefault(require("./translations/en.json"));
9
9
  var fr_json_1 = __importDefault(require("./translations/fr.json"));
10
10
  var de_json_1 = __importDefault(require("./translations/de.json"));
11
11
  var nl_json_1 = __importDefault(require("./translations/nl.json"));
12
+ var it_json_1 = __importDefault(require("./translations/it.json"));
12
13
  /**
13
14
  * i18n instance of the Inspection CApture Web package. You can use this instance to automatically sync your application
14
15
  * current language with the one used by the components of the package.
@@ -19,6 +20,7 @@ var i18nInspectionCaptureWeb = (0, common_1.i18nCreateSDKInstance)({
19
20
  fr: { translation: fr_json_1.default },
20
21
  de: { translation: de_json_1.default },
21
22
  nl: { translation: nl_json_1.default },
23
+ it: { translation: it_json_1.default },
22
24
  },
23
25
  });
24
26
  exports.i18nInspectionCaptureWeb = i18nInspectionCaptureWeb;
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "closeConfirm": {
29
29
  "message": "Sind Sie sicher, dass Sie das Erfassungstool schließen wollen?",
30
- "cancel": "Abbrechen",
30
+ "cancel": "Nein",
31
31
  "confirm": "Ja"
32
32
  },
33
33
  "guidelines": {
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "closeConfirm": {
29
29
  "message": "Are you sure you want to close the capture tool?",
30
- "cancel": "Cancel",
30
+ "cancel": "No",
31
31
  "confirm": "Yes"
32
32
  },
33
33
  "guidelines": {
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "closeConfirm": {
29
29
  "message": "Êtes-vous sûr(e) de vouloir fermer l'outil de capture ?",
30
- "cancel": "Annuler",
30
+ "cancel": "Non",
31
31
  "confirm": "Oui"
32
32
  },
33
33
  "guidelines": {
@@ -0,0 +1,108 @@
1
+ {
2
+ "photo": {
3
+ "badConnectionWarning": {
4
+ "message": "Stiamo riscontrando problemi di connessione. Il caricamento delle foto potrebbe richiedere più tempo del solito.",
5
+ "confirm": "Ho capito"
6
+ },
7
+ "hud": {
8
+ "sight": { "addDamageBtn": "Danno" },
9
+ "addDamage": {
10
+ "cancelBtn": "Annulla",
11
+ "damagedPartCounter": "1 / 2 • Parte danneggiata",
12
+ "closeupPictureCounter": "2 / 2 • Danno in primo piano",
13
+ "infoBtn": "Posiziona il mirino sulla parte danneggiata e premi il pulsante di scatto",
14
+ "infoCloseup": "Scatta una foto ravvicinata del danno",
15
+ "selectPart": "Seleziona la parte danneggiata. Usa le frecce per ruotare il veicolo e vedere l'altro lato",
16
+ "selectParts": "Seleziona le parti danneggiate. Usa le frecce per ruotare il veicolo e vedere l'altro lato."
17
+ },
18
+ "error": {
19
+ "retry": "Riprova",
20
+ "missingTasks": "L'ispezione fornita non contiene alcune attività richieste dal modulo di acquisizione attuale.",
21
+ "invalidToken": "Il token di autenticazione utilizzato non è valido.",
22
+ "expiredToken": "Il token di autenticazione utilizzato è scaduto.",
23
+ "insufficientAuth": "Non hai le autorizzazioni necessarie per eseguire questa azione.",
24
+ "inspectionLoading": "Si è verificato un errore durante il caricamento dell'ispezione. Riprova tra qualche istante o contatta il supporto con il seguente ID ispezione:"
25
+ },
26
+ "closeConfirm": {
27
+ "message": "Sei sicuro di voler chiudere lo strumento di acquisizione?",
28
+ "cancel": "Annulla",
29
+ "confirm": "Sì"
30
+ },
31
+ "guidelines": {
32
+ "defaultGuideline": "Le indicazioni sul punto di vista dell'immagine possono essere visualizzate qui.",
33
+ "disable": "Non mostrare più",
34
+ "validate": "Ok"
35
+ },
36
+ "tutorial": {
37
+ "welcome": "Benvenuto alla tua prima ispezione!",
38
+ "title": "Come usarlo",
39
+ "guideline": "Fai il giro del veicolo per scattare tutte le foto e segui le istruzioni in alto per posizionarti con l'angolazione corretta.",
40
+ "sightTutorial": "Usa l'immagine in basso a sinistra per aiutarti nell'inquadratura.<br>Tocca per vedere una spiegazione dettagliata.",
41
+ "sight": "Allinea il veicolo con le linee il più possibile per ottenere la foto migliore.<br>Premi il pulsante di scatto per scattare la foto.",
42
+ "next": "Avanti"
43
+ },
44
+ "sightTutorial": {
45
+ "tip": "Consiglio",
46
+ "defaultTutorialWithImage": "Ecco un'immagine di riferimento.\nCerca di riprodurre l'inquadratura il più fedelmente possibile.",
47
+ "defaultTutorialWithoutImage": "Posizionati come indicato nello schema a sinistra,\nassicurandoti che la fotocamera sia all'altezza giusta."
48
+ }
49
+ },
50
+ "gallery": { "next": "Avanti: foto del veicolo" }
51
+ },
52
+ "video": {
53
+ "introduction": { "title": "Registra un video di ispezione del veicolo" },
54
+ "permissions": {
55
+ "camera": {
56
+ "title": "Fotocamera",
57
+ "description": "Per registrare un video, devi autorizzare l'accesso alla fotocamera del dispositivo"
58
+ },
59
+ "compass": {
60
+ "title": "Bussola",
61
+ "description": "Per rilevare una rotazione completa a 360° del veicolo, devi autorizzare l'accesso alla bussola del dispositivo"
62
+ },
63
+ "confirm": "Gestisci autorizzazioni"
64
+ },
65
+ "tutorial": {
66
+ "start": {
67
+ "title": "Inizia dalla parte anteriore",
68
+ "description": "Mantieni una distanza di un metro e gira lentamente intorno al veicolo, catturando la linea del tetto fino al suolo."
69
+ },
70
+ "finish": {
71
+ "title": "Termina dove hai iniziato",
72
+ "description": "La registrazione dovrebbe essere completata in circa 45 secondi."
73
+ },
74
+ "photos": {
75
+ "title": "Scatta foto se necessario",
76
+ "description": "Premi il pulsante di scatto per scattare foto di remarketing o danni durante la registrazione."
77
+ },
78
+ "confirm": "Registra un video"
79
+ },
80
+ "recording": {
81
+ "discardDialog": {
82
+ "message": "Vuoi annullare il video? Non hai completato il giro del veicolo.",
83
+ "keepRecording": "Continua la registrazione",
84
+ "discardVideo": "Annulla il video"
85
+ },
86
+ "fastMovementsDialog": {
87
+ "walkingTooFast": "Stai andando troppo veloce! Rallenta un po'. Dovresti impiegare circa un minuto per girare intorno al veicolo.",
88
+ "phoneShaking": "Il tuo dispositivo sta tremando troppo! Cerca di tenere la fotocamera stabile durante la registrazione.",
89
+ "confirm": "OK"
90
+ },
91
+ "tooltip": {
92
+ "start": "Quando sei davanti al veicolo, premi il pulsante per iniziare a registrare il video.",
93
+ "end": "Quando hai completato il giro del veicolo, premi il pulsante per terminare la registrazione."
94
+ }
95
+ },
96
+ "processing": {
97
+ "processing": "Elaborazione del video...",
98
+ "uploading": "Caricamento del video...",
99
+ "success": "Elaborazione del video completata!",
100
+ "error": "Si è verificato un errore durante la finalizzazione dell'ispezione. ID ispezione:",
101
+ "done": "Fatto"
102
+ }
103
+ },
104
+ "orientationEnforcer": {
105
+ "title": "Ruota il tuo dispositivo.",
106
+ "description": "Potrebbe essere necessario sbloccare l'orientamento del dispositivo nelle impostazioni del telefono."
107
+ }
108
+ }
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "closeConfirm": {
29
29
  "message": "Weet je zeker dat je de capture tool wilt sluiten?",
30
- "cancel": "Annuleren",
30
+ "cancel": "Nee",
31
31
  "confirm": "Ja"
32
32
  },
33
33
  "guidelines": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monkvision/inspection-capture-web",
3
- "version": "5.1.7",
3
+ "version": "5.2.0",
4
4
  "license": "BSD-3-Clause-Clear",
5
5
  "packageManager": "yarn@3.2.4",
6
6
  "description": "MonkJs inspection capture package for React (web) used to implement the Monk inspection capture workflow",
@@ -28,12 +28,12 @@
28
28
  "lint:fix": "yarn run prettier:fix && yarn run eslint:fix"
29
29
  },
30
30
  "dependencies": {
31
- "@monkvision/analytics": "5.1.7",
32
- "@monkvision/camera-web": "5.1.7",
33
- "@monkvision/common": "5.1.7",
34
- "@monkvision/common-ui-web": "5.1.7",
35
- "@monkvision/network": "5.1.7",
36
- "@monkvision/sights": "5.1.7",
31
+ "@monkvision/analytics": "5.2.0",
32
+ "@monkvision/camera-web": "5.2.0",
33
+ "@monkvision/common": "5.2.0",
34
+ "@monkvision/common-ui-web": "5.2.0",
35
+ "@monkvision/network": "5.2.0",
36
+ "@monkvision/sights": "5.2.0",
37
37
  "i18next": "^23.4.5",
38
38
  "react-i18next": "^13.2.0"
39
39
  },
@@ -44,13 +44,13 @@
44
44
  "react-router-dom": "^6.22.3"
45
45
  },
46
46
  "devDependencies": {
47
- "@monkvision/eslint-config-base": "5.1.7",
48
- "@monkvision/eslint-config-typescript": "5.1.7",
49
- "@monkvision/eslint-config-typescript-react": "5.1.7",
50
- "@monkvision/jest-config": "5.1.7",
51
- "@monkvision/prettier-config": "5.1.7",
52
- "@monkvision/test-utils": "5.1.7",
53
- "@monkvision/typescript-config": "5.1.7",
47
+ "@monkvision/eslint-config-base": "5.2.0",
48
+ "@monkvision/eslint-config-typescript": "5.2.0",
49
+ "@monkvision/eslint-config-typescript-react": "5.2.0",
50
+ "@monkvision/jest-config": "5.2.0",
51
+ "@monkvision/prettier-config": "5.2.0",
52
+ "@monkvision/test-utils": "5.2.0",
53
+ "@monkvision/typescript-config": "5.2.0",
54
54
  "@testing-library/react": "^12.1.5",
55
55
  "@testing-library/react-hooks": "^8.0.1",
56
56
  "@types/copyfiles": "^2",
@@ -93,5 +93,5 @@
93
93
  "url": "https://github.com/monkvision/monkjs/issues"
94
94
  },
95
95
  "homepage": "https://github.com/monkvision/monkjs",
96
- "gitHead": "6cd10ecefd109e4676a701f3e498efd6f726ff4f"
96
+ "gitHead": "5380665942c8c075485142183e431996657e70d1"
97
97
  }