Skip to content

Commit 30b8633

Browse files
committed
Added compliance logic, InspectionGallery and ImageDetailedView components
1 parent 9474a3d commit 30b8633

File tree

109 files changed

+4616
-728
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+4616
-728
lines changed

apps/demo-app/src/components/App.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import { Outlet, useNavigate } from 'react-router-dom';
22
import { MonkAppParamsProvider, MonkProvider, useMonkTheme } from '@monkvision/common';
3+
import { useTranslation } from 'react-i18next';
34
import { Page } from '../pages';
45

56
export function App() {
67
const navigate = useNavigate();
8+
const { i18n } = useTranslation();
79
const { rootStyles } = useMonkTheme();
810

911
return (
10-
<MonkAppParamsProvider onFetchAuthToken={() => navigate(Page.CREATE_INSPECTION)}>
12+
<MonkAppParamsProvider
13+
onFetchAuthToken={() => navigate(Page.CREATE_INSPECTION)}
14+
onUpdateLanguage={(lang) => i18n.changeLanguage(lang)}
15+
>
1116
<MonkProvider>
1217
<div className='app-container' style={rootStyles}>
1318
<Outlet />

apps/demo-app/src/pages/PhotoCapturePage/PhotoCapturePage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useTranslation } from 'react-i18next';
22
import { getEnvOrThrow, useMonkAppParams, zlibCompress } from '@monkvision/common';
3-
import { VehicleType } from '@monkvision/types';
3+
import { DeviceOrientation, VehicleType } from '@monkvision/types';
44
import { PhotoCapture } from '@monkvision/inspection-capture-web';
55
import { getSights } from '../../config';
66
import styles from './PhotoCapturePage.module.css';
@@ -59,6 +59,8 @@ export function PhotoCapturePage() {
5959
sights={getSights(vehicleType)}
6060
onComplete={handleComplete}
6161
lang={i18n.language}
62+
enforceOrientation={DeviceOrientation.LANDSCAPE}
63+
allowSkipRetake={true}
6264
/>
6365
</div>
6466
);

configs/test-utils/src/__mocks__/@monkvision/common-ui-web.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export = {
88
BackdropDialog: jest.fn(() => <></>),
99
Button: jest.fn(() => <></>),
1010
DynamicSVG: jest.fn(() => <></>),
11-
FullscreenImageModal: jest.fn(() => <></>),
12-
FullscreenModal: jest.fn(() => <></>),
1311
Icon: jest.fn(() => <></>),
12+
ImageDetailedView: jest.fn(() => <></>),
13+
InspectionGallery: jest.fn(() => <></>),
1414
SightOverlay: jest.fn(() => <></>),
1515
Slider: jest.fn(() => <></>),
1616
Spinner: jest.fn(() => <></>),

configs/test-utils/src/__mocks__/@monkvision/common.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const {
99
toCamelCase,
1010
getRGBAFromString,
1111
getHexFromRGBA,
12-
changeAlpha,
1312
shadeColor,
1413
InteractiveVariation,
1514
getInteractiveVariants,
@@ -21,6 +20,8 @@ const {
2120
uniq,
2221
flatMap,
2322
STORAGE_KEY_AUTH_TOKEN,
23+
complianceIssueLabels,
24+
imageStatusLabels,
2425
} = jest.requireActual('@monkvision/common');
2526

2627
export = {
@@ -33,7 +34,6 @@ export = {
3334
toCamelCase,
3435
getRGBAFromString,
3536
getHexFromRGBA,
36-
changeAlpha,
3737
shadeColor,
3838
InteractiveVariation,
3939
getInteractiveVariants,
@@ -44,6 +44,9 @@ export = {
4444
uniq,
4545
flatMap,
4646
STORAGE_KEY_AUTH_TOKEN,
47+
createEmptyMonkState,
48+
complianceIssueLabels,
49+
imageStatusLabels,
4750

4851
/* Mocks */
4952
useMonkTheme: jest.fn(() => createTheme()),
@@ -58,10 +61,11 @@ export = {
5861
useI18nSync: jest.fn(),
5962
i18nCreateSDKInstance: jest.fn(),
6063
i18nWrap: jest.fn((component) => component),
61-
useInteractiveStatus: jest.fn(({ componentHandlers }) => ({
64+
useInteractiveStatus: jest.fn((props) => ({
6265
status: InteractiveStatus.DEFAULT,
63-
eventHandlers: componentHandlers,
66+
eventHandlers: props?.componentHandlers,
6467
})),
68+
changeAlpha: jest.fn((c) => c),
6569
useQueue: jest.fn(() => ({
6670
length: 0,
6771
processingCount: 0,

configs/test-utils/src/__mocks__/@monkvision/network.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ export = {
2424
})),
2525
MonkApi,
2626
useMonkApi: jest.fn(() => MonkApi),
27+
useInspectionPoll: jest.fn(),
2728
};

packages/common-ui-web/README.md

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -132,95 +132,95 @@ function App() {
132132

133133
---
134134

135-
## FullscreenImageModal
135+
## Icon
136136
### Description
137-
Component used to display a full-screen modal for an image and able the user to zoom on it.
138-
137+
An Icon component that displays an icon based on a given name. The list of icons is available in the official Monk SDK
138+
documentation.
139139

140140
### Example
141141
```tsx
142-
import { FullscreenImageModal } from '@monkvision/common-ui-web';
142+
import { Icon } from '@monkvision/common-ui-web';
143143

144144
function App() {
145-
const [showFullscreenImageModal, setShowFullscreenImageModal] = useState(true);
146-
147-
return (
148-
<FullscreenImageModal
149-
url={'https://example.com/image.jpg'}
150-
show={showFullscreenImageModal}
151-
label='Hello World!'
152-
onClose={() => setShowFullscreenImageModal(false)}
153-
/>
154-
);
145+
return <Icon icon='add' primaryColor='text-white' size={30} />;
155146
}
156147
```
157148

158149
### Props
159-
| Prop | Type | Description | Required | Default Value |
160-
|---------|--------------|-----------------------------------------------------------------------------------------------|----------|---------------|
161-
| url | string | The URL of the image to display. | ✔️ | |
162-
| show | boolean | Boolean indicating if the fullscreen image modal is displayed on the screen. | | `false` |
163-
| label | string | Label displayed in the header at the top of the image modal. | | `''` |
164-
| onClose | `() => void` | Callback called when the user presses the close button in the header at the top of the modal. | | |
150+
| Prop | Type | Description | Required | Default Value |
151+
|--------------|-----------|------------------------------------------------------------|----------|---------------|
152+
| icon | number | The name of the icon to display. | ✔️ | |
153+
| size | number | The size (width and height, in pixels) of the icon. | | `50` |
154+
| primaryColor | ColorProp | The name or the hexcode of the color to apply to the icon. | | `black` |
165155

166156
---
167157

168-
## FullscreenModal
158+
## ImageDetailedView
169159
### Description
170-
Component used to display a full screen modal on top of the screen. The content of the modal must be passed as children
171-
to this component.
160+
This component is used to display the preview of an inspection image, as well as additional data such as its label etc.
161+
If this component is used mid-capture, set the `captureMode` prop to `true` so that you'll enable features such as
162+
compliance errors, retakes etc.
172163

173164
### Example
174165

175166
```tsx
176-
import { FullscreenModal } from '@monkvision/common-ui-web';
167+
import { ImageDetailedView } from '@monkvision/common-ui-web';
168+
import { useMonkState } from '@monkvision/common';
169+
import { useMemo } from 'react';
177170

178-
function App() {
179-
const [showFullscreenModal, setShowFullscreenModal] = useState(true);
171+
function ImageViewer({ id }: ImageViewerProps) {
172+
const { state } = useMonkState();
173+
const image = useMemo(() => state.images.find((i) => i.id === id), [state.images, id]);
180174

181-
return (
182-
<FullscreenModal
183-
show={showFullscreenModal}
184-
title='Hello World!'
185-
onClose={() => setShowFullscreenModal(false)}
186-
>
187-
<div>
188-
This is the content of the modal!
189-
</div>
190-
</FullscreenModal>
191-
);
175+
return <ImageDetailedView image={image} />;
192176
}
193177
```
194178

195179
### Props
196-
| Prop | Type | Description | Required | Default Value |
197-
|--------------|--------------|-----------------------------------------------------------------------------------------------|----------|---------------|
198-
| show | boolean | Boolean indicating if the fullscreen modal is displayed on the screen. | | `false` |
199-
| title | string | Title displayed in the header at the top of the modal. | | `''` |
200-
| onClose | `() => void` | Callback called when the user presses the close button in the header at the top of the modal. | | |
180+
| Prop | Type | Description | Required | Default Value |
181+
|---------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------|----------|---------------|
182+
| image | Image | The image to display the details of. | ✔️ | |
183+
| captureMode | boolean | Boolean indicating if this component is displayed in "capture" mode. | ✔️ | `false` |
184+
| lang | string | The language to be used by the component. | | `en` |
185+
| showGalleryButton | boolean | Boolean indicating if the gallery button must be displayed or not. | | `true` |
186+
| onClose | () => void | Callback called when the user presses the close button. | | |
187+
| onNavigateToGallery | () => void | Callback called when the user presses the gallery button if it is displayed. | | |
188+
| showCaptureButton | boolean | Boolean indicating if the capture button must be displayed or not. This prop can only be specified if `captureMode` is set to true. | | `true` |
189+
| onNavigateToCapture | () => void | Callback called when the user presses the capture button. This prop can only be specified if `captureMode` is set to true. | | |
190+
| onRetake | () => void | Callback called when the user presses the retake button. This prop can only be specified if `captureMode` is set to true. | | |
201191

202192
---
203193

204-
## Icon
194+
## InspectionGallery
205195
### Description
206-
An Icon component that displays an icon based on a given name. The list of icons is available in the official Monk SDK
207-
documentation.
196+
This component is used to display a gallery of pictures taken during an inspection. If this component is used
197+
mid-capture, set the `captureMode` prop to `true` so that you'll enable features such as compliance errors, retakes etc.
208198

209199
### Example
210200
```tsx
211-
import { Icon } from '@monkvision/common-ui-web';
201+
import { InspectionGallery } from '@monkvision/common-ui-web';
212202

213203
function App() {
214-
return <Icon icon='add' primaryColor='text-white' size={30} />;
204+
return <InspectionGallery icon='add' primaryColor='text-white' size={30} />;
215205
}
216206
```
217207

218208
### Props
219-
| Prop | Type | Description | Required | Default Value |
220-
|--------------|-----------|------------------------------------------------------------|----------|---------------|
221-
| icon | number | The name of the icon to display. | ✔️ | |
222-
| size | number | The size (width and height, in pixels) of the icon. | | `50` |
223-
| primaryColor | ColorProp | The name or the hexcode of the color to apply to the icon. | | `black` |
209+
| Prop | Type | Description | Required | Default Value |
210+
|---------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------|---------------|
211+
| inspectionId | string | The ID of the inspection to display the images of. | ✔️ | |
212+
| apiConfig | ApiConfig | The config used to communicate with the API. | ✔️ | |
213+
| captureMode | boolean | Boolean indicating if this component is displayed in "capture" mode. | ✔️ | |
214+
| lang | string | The language used by the InspectionGallery component. | | `en` |
215+
| refreshIntervalMs | number | The delay (in milliseconds) between each `getInspection` request made to the API when polling the status of the inspection. | | `1000` |
216+
| showBackButton | boolean | Boolean indicating if the back button of the gallery top bar should be displayed or not. | | `false` |
217+
| onBack | () => void | Callback called when the user presses the back button if it is displayed. | | |
218+
| onValidate | () => void | Callback called when the user presses the validate button. | | |
219+
| sights | Sight[] | The list of sights to be capture in the current capture flow. This prop can only be specified if `captureMode` is set to true. | ✔️ (if `captureMode` is `true`) | |
220+
| allowSkipRetake | boolean | Boolean indicating if the user should be allowed to skip the retaking of non-compliant pictures before validating the inspection. This prop can only be specified if `captureMode` is set to true. | | `false` |
221+
| onNavigateToCapture | () => void | Callback called when the user wants to navigate back to the capture component. This prop can only be specified if `captureMode` is set to true. | | |
222+
| enableCompliance | boolean | Boolean indicating if compliance checks should be enabled or not. This prop can only be specified if `captureMode` is set to true. | | |
223+
| complianceIssues | ComplianceIssue[] | If compliance checks are enable, this property can be used to select a list of compliance issues to check. This prop can only be specified if `captureMode` is set to true. | | |
224224

225225
---
226226

packages/common-ui-web/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525
},
2626
"dependencies": {
2727
"@monkvision/common": "4.0.0",
28+
"@monkvision/sights": "4.0.0",
2829
"@monkvision/types": "4.0.0",
29-
"css": "^3.0.0"
30+
"css": "^3.0.0",
31+
"i18next": "^23.4.5",
32+
"react-i18next": "^13.2.0"
3033
},
3134
"peerDependencies": {
3235
"react": "^17.0.2",

packages/common-ui-web/src/components/Button/Button.styles.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export const styles: Styles = {
2626
cursor: 'pointer',
2727
borderWidth: 0,
2828
},
29+
buttonIconOnly: {
30+
padding: 16,
31+
},
2932
buttonDisabled: {
3033
opacity: 0.37,
3134
cursor: 'default',
@@ -36,6 +39,9 @@ export const styles: Styles = {
3639
lineHeight: '20px',
3740
letterSpacing: 0.1,
3841
},
42+
buttonIconOnlySmall: {
43+
padding: 6,
44+
},
3945
buttonOutline: {
4046
borderStyle: 'solid',
4147
borderWidth: 2,

packages/common-ui-web/src/components/Button/Button.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export const Button = forwardRef<HTMLButtonElement, PropsWithChildren<ButtonProp
6565
preserveWidthOnLoading,
6666
status,
6767
hasChildren: !!children,
68+
icon,
6869
});
6970

7071
const content = useMemo(

packages/common-ui-web/src/components/Button/hooks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ export function useButtonStyle(params: MonkButtonStyleParams): MonkButtonStyle {
163163
...(params.size === 'small' ? styles['buttonSmall'] : {}),
164164
...(params.variant === 'outline' ? styles['buttonOutline'] : {}),
165165
...(params.variant === 'text-link' ? styles['buttonTextLink'] : {}),
166+
...(!params.hasChildren && params.icon ? styles['buttonIconOnly'] : {}),
167+
...(!params.hasChildren && params.icon && params.size === 'small'
168+
? styles['buttonIconOnlySmall']
169+
: {}),
166170
color: foregroundColor,
167171
borderColor: foregroundColor,
168172
backgroundColor,

0 commit comments

Comments
 (0)