Skip to content

Commit

Permalink
Added compliance notification badge
Browse files Browse the repository at this point in the history
  • Loading branch information
souyahia-monk committed Apr 30, 2024
1 parent ab845e3 commit 0820edc
Show file tree
Hide file tree
Showing 20 changed files with 424 additions and 91 deletions.
2 changes: 2 additions & 0 deletions configs/test-utils/src/__mocks__/@monkvision/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const {
STORAGE_KEY_AUTH_TOKEN,
complianceIssueLabels,
imageStatusLabels,
getInspectionImages,
} = jest.requireActual('@monkvision/common');

export = {
Expand All @@ -47,6 +48,7 @@ export = {
createEmptyMonkState,
complianceIssueLabels,
imageStatusLabels,
getInspectionImages,

/* Mocks */
useMonkTheme: jest.fn(() => createTheme()),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from 'react';
import { Image, ImageStatus, Sight } from '@monkvision/types';
import { MonkState, useMonkState } from '@monkvision/common';
import { ImageStatus, Sight } from '@monkvision/types';
import { getInspectionImages, MonkState, useMonkState } from '@monkvision/common';
import { useInspectionPoll } from '@monkvision/network';
import { InspectionGalleryItem, InspectionGalleryProps } from '../types';

Expand Down Expand Up @@ -62,35 +62,12 @@ function getItems(
enableCompliance: boolean,
inspectionSights?: Sight[],
): InspectionGalleryItem[] {
const inspection = entities.inspections.find((i) => i.id === inspectionId);
const items: InspectionGalleryItem[] = [];
entities.images
.filter((image) => inspection?.images.includes(image.id))
.forEach((image) => {
const item: InspectionGalleryItem = { isTaken: true, isAddDamage: false, image };
const itemSightId = image.additionalData?.sight_id;
if (!captureMode || !itemSightId) {
items.push(item);
} else {
const index = items.findIndex(
(i) => !i.isAddDamage && i.isTaken && i.image.additionalData?.sight_id === itemSightId,
);
if (index >= 0) {
const itemDateISO = image.additionalData?.created_at;
const alreadyExistingImageDateISO = (items[index] as { image: Image }).image
.additionalData?.created_at;
if (
alreadyExistingImageDateISO &&
itemDateISO &&
new Date(itemDateISO) > new Date(alreadyExistingImageDateISO)
) {
items[index] = item;
}
} else {
items.push(item);
}
}
});
const images = getInspectionImages(inspectionId, entities.images, captureMode);
const items: InspectionGalleryItem[] = images.map((image) => ({
isTaken: true,
isAddDamage: false,
image,
}));
inspectionSights?.forEach((sight) => {
if (
!items.find(
Expand Down Expand Up @@ -141,7 +118,11 @@ export function useInspectionGalleryItems(props: InspectionGalleryProps): Inspec
id: props.inspectionId,
apiConfig: props.apiConfig,
compliance: props.captureMode
? { enableCompliance, complianceIssues: props.complianceIssues }
? {
enableCompliance,
complianceIssues: props.complianceIssues,
useLiveCompliance: props.useLiveCompliance,
}
: undefined,
delay: shouldFetch ? props.refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS : null,
onSuccess,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { renderHook } from '@testing-library/react-hooks';
import { sights } from '@monkvision/sights';
import {
ComplianceIssue,
ComplianceOptions,
Image,
ImageStatus,
Inspection,
} from '@monkvision/types';
import { ComplianceIssue, ComplianceOptions, Image, ImageStatus } from '@monkvision/types';
import { createEmptyMonkState, useMonkState } from '@monkvision/common';
import { useInspectionPoll } from '@monkvision/network';
import { act } from '@testing-library/react';
Expand All @@ -33,18 +27,16 @@ describe('useInspectionGalleryItems hook', () => {
it('should initialize the gallery items using the local Monk state', () => {
const initialProps = createProps();
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1', 'image-2'],
} as unknown as Inspection);
state.images.push(
{
id: 'image-1',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-2' },
status: ImageStatus.SUCCESS,
} as unknown as Image,
{
id: 'image-2',
inspectionId: initialProps.inspectionId,
status: ImageStatus.SUCCESS,
} as unknown as Image,
);
Expand All @@ -65,22 +57,21 @@ describe('useInspectionGalleryItems hook', () => {
it('should properly update the items after each inspection poll', () => {
const initialProps = createProps();
const entities = createEmptyMonkState();
entities.inspections.push({
id: initialProps.inspectionId,
images: ['image-1', 'image-2', 'image-3'],
} as unknown as Inspection);
entities.images.push(
{
id: 'image-1',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1' },
status: ImageStatus.SUCCESS,
} as unknown as Image,
{
id: 'image-2',
inspectionId: initialProps.inspectionId,
status: ImageStatus.SUCCESS,
} as unknown as Image,
{
id: 'image-3',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-3' },
status: ImageStatus.SUCCESS,
} as unknown as Image,
Expand Down Expand Up @@ -112,22 +103,21 @@ describe('useInspectionGalleryItems hook', () => {
it('should put items to retake first in the list', () => {
const initialProps = createProps();
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1', 'image-2', 'image-3'],
} as unknown as Inspection);
state.images.push(
{
id: 'image-1',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1' },
status: ImageStatus.SUCCESS,
} as unknown as Image,
{
id: 'image-2',
inspectionId: initialProps.inspectionId,
status: ImageStatus.NOT_COMPLIANT,
} as unknown as Image,
{
id: 'image-3',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-3' },
status: ImageStatus.NOT_COMPLIANT,
} as unknown as Image,
Expand All @@ -150,21 +140,20 @@ describe('useInspectionGalleryItems hook', () => {
const initialProps = createProps();
initialProps.captureMode = false;
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1', 'image-2', 'image-3'],
} as unknown as Inspection);
state.images.push(
{
id: 'image-1',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1' },
} as unknown as Image,
{
id: 'image-2',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-2' },
} as unknown as Image,
{
id: 'image-3',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-3' },
} as unknown as Image,
);
Expand Down Expand Up @@ -194,21 +183,20 @@ describe('useInspectionGalleryItems hook', () => {
const initialProps = createProps();
initialProps.captureMode = true;
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1', 'image-2', 'image-3'],
} as unknown as Inspection);
state.images.push(
{
id: 'image-1',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1', created_at: '2020-01-01T01:01:01.001Z' },
} as unknown as Image,
{
id: 'image-2',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1', created_at: '1999-01-01T01:01:01.001Z' },
} as unknown as Image,
{
id: 'image-3',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1', created_at: '2023-01-01T01:01:01.001Z' },
} as unknown as Image,
);
Expand All @@ -229,17 +217,15 @@ describe('useInspectionGalleryItems hook', () => {
const initialProps = createProps();
initialProps.captureMode = false;
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1', 'image-2'],
} as unknown as Inspection);
state.images.push(
{
id: 'image-1',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1', created_at: '2020-01-01T01:01:01.001Z' },
} as unknown as Image,
{
id: 'image-2',
inspectionId: initialProps.inspectionId,
additionalData: { sight_id: 'test-sight-1', created_at: '1999-01-01T01:01:01.001Z' },
} as unknown as Image,
);
Expand Down Expand Up @@ -290,12 +276,9 @@ describe('useInspectionGalleryItems hook', () => {
const initialProps = createProps();
initialProps.refreshIntervalMs = 1234;
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1'],
} as unknown as Inspection);
state.images.push({
id: 'image-1',
inspectionId: initialProps.inspectionId,
status: ImageStatus.UPLOADING,
} as unknown as Image);
(useMonkState as jest.Mock).mockImplementationOnce(() => ({ state }));
Expand All @@ -314,12 +297,9 @@ describe('useInspectionGalleryItems hook', () => {
const initialProps = createProps();
initialProps.refreshIntervalMs = 1234;
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1'],
} as unknown as Inspection);
state.images.push({
id: 'image-1',
inspectionId: initialProps.inspectionId,
status: ImageStatus.COMPLIANCE_RUNNING,
} as unknown as Image);
(useMonkState as jest.Mock).mockImplementationOnce(() => ({ state }));
Expand All @@ -338,12 +318,9 @@ describe('useInspectionGalleryItems hook', () => {
const initialProps = createProps();
initialProps.refreshIntervalMs = undefined;
const state = createEmptyMonkState();
state.inspections.push({
id: initialProps.inspectionId,
images: ['image-1'],
} as unknown as Inspection);
state.images.push({
id: 'image-1',
inspectionId: initialProps.inspectionId,
status: ImageStatus.COMPLIANCE_RUNNING,
} as unknown as Image);
(useMonkState as jest.Mock).mockImplementationOnce(() => ({ state }));
Expand Down
13 changes: 13 additions & 0 deletions packages/common/README/UTILITIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,19 @@ This function creates and returns a new Promise that will resolve to void after

---

# State Utils
### getInspectionImages
```typescript
import { getInspectionImages } from '@monkvision/common';

console.log(getInspectionImages(inspectionId, images, filterRetakes));
// Returns an array of all the images having the given inspectionId.
```
Utility function that extracts the images of the given inspection. Set `filterRetakes` to `false` to filter retaken
pictures.

---

# String Utils
### suffix
```typescript
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './promise.utils';
export * from './zlib.utils';
export * from './browser.utils';
export * from './env.utils';
export * from './state.utils';
41 changes: 41 additions & 0 deletions packages/common/src/utils/state.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Image } from '@monkvision/types';

/**
* Utility function that extracts the images of the given inspection.
*
* @param inspectionId The ID of the inspection to get the images of.
* @param images Array containing every image existing in the current local state.
* @param filterRetakes Boolean indicating if retaken pictures should be filtered out or not (default: false).
*/
export function getInspectionImages(
inspectionId: string,
images: Image[],
filterRetakes = false,
): Image[] {
const inspectionImages = images.filter((image) => image.inspectionId === inspectionId);
if (!filterRetakes) {
return inspectionImages;
}
const filteredRetakes: Image[] = [];
inspectionImages.forEach((image) => {
if (image.additionalData?.sight_id) {
const index = filteredRetakes.findIndex(
(i) => i.additionalData?.sight_id === image.additionalData?.sight_id,
);
if (index >= 0) {
const imageDateISO = image.additionalData?.created_at;
const alreadyExistingImageDateISO = filteredRetakes[index].additionalData?.created_at;
if (
alreadyExistingImageDateISO &&
imageDateISO &&
new Date(imageDateISO) > new Date(alreadyExistingImageDateISO)
) {
filteredRetakes[index] = image;
}
return;
}
}
filteredRetakes.push(image);
});
return filteredRetakes;
}
Loading

0 comments on commit 0820edc

Please sign in to comment.