Skip to content

Commit f44f7f9

Browse files
committed
Added getInspections to network package
1 parent afd80da commit f44f7f9

File tree

11 files changed

+269
-7
lines changed

11 files changed

+269
-7
lines changed

packages/network/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,20 @@ Delete a damage of an inspection.
210210
|-----------|---------------------|-----------------------------|----------|
211211
| options | DeleteDamageOptions | The options of the request. | ✔️ |
212212

213+
### getInspections
214+
```typescript
215+
import { MonkApi } from '@monkvision/network';
216+
217+
MonkApi.getInspections(options, apiConfig, dispatch);
218+
```
219+
220+
Fetch the details of multiple inspections using the provided filters. The resulting action of this request will contain
221+
a list of all entities that match the specified criteria.
222+
223+
| Parameter | Type | Description | Required |
224+
|-----------|-----------------------|-----------------------------|----------|
225+
| options | getInspectionsOptions | The options of the request. | ✔️ |
226+
213227
# React Tools
214228
In order to simply integrate the Monk Api requests into your React app, you can make use of the `useMonkApi` hook. This
215229
custom hook returns a custom version of the `MonkApi` object described in the section above, in which the requests do

packages/network/src/api/api.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { getInspection, createInspection, updateAdditionalData } from './inspection';
1+
import {
2+
getInspection,
3+
createInspection,
4+
updateAdditionalData,
5+
getInspections,
6+
} from './inspection';
27
import { addImage } from './image';
38
import { startInspectionTasks, updateTaskStatus } from './task';
49
import { getLiveConfig } from './liveConfigs';
@@ -12,6 +17,7 @@ import { createDamage, deleteDamage } from './damage';
1217
*/
1318
export const MonkApi = {
1419
getInspection,
20+
getInspections,
1521
createInspection,
1622
addImage,
1723
updateTaskStatus,

packages/network/src/api/inspection/mappers.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
Severity,
2525
SeverityResult,
2626
SeverityResultTargetType,
27+
SortOrder,
2728
Task,
2829
TaskName,
2930
Vehicle,
@@ -40,6 +41,7 @@ import {
4041
ApiImagesOCRTaskPostComponent,
4142
ApiInspectionGet,
4243
ApiInspectionPost,
44+
ApiInspectionsGet,
4345
ApiPartSeverityValue,
4446
ApiPricingTaskPostComponent,
4547
ApiPricingV2Details,
@@ -374,6 +376,60 @@ function mapInspection(
374376
};
375377
}
376378

379+
export function mapApiInspectionsGet(
380+
response: ApiInspectionsGet,
381+
thumbnailDomain: string,
382+
): MonkState {
383+
const state: MonkState = {
384+
damages: [],
385+
images: [],
386+
inspections: [],
387+
parts: [],
388+
renderedOutputs: [],
389+
severityResults: [],
390+
tasks: [],
391+
vehicles: [],
392+
views: [],
393+
pricings: [],
394+
partOperations: [],
395+
};
396+
if (!response.data) {
397+
return state;
398+
}
399+
return response.data.reduce<MonkState>((acc, inspection) => {
400+
const { images, renderedOutputs, imageIds, renderedOutputIds, viewIds } = mapImages(
401+
inspection as ApiInspectionGet,
402+
thumbnailDomain,
403+
);
404+
const { damages, damageIds } = mapDamages(inspection as ApiInspectionGet);
405+
const { parts, partIds } = mapParts(inspection as ApiInspectionGet);
406+
const { pricings, pricingIds } = mapPricingV2(inspection as ApiInspectionGet);
407+
const vehicle = mapVehicle(inspection as ApiInspectionGet);
408+
const mappedInspection = mapInspection(inspection as ApiInspectionGet, {
409+
imageIds,
410+
renderedOutputIds,
411+
viewIds,
412+
damageIds,
413+
partIds,
414+
severityResultIds: [],
415+
taskIds: [],
416+
pricingIds,
417+
vehicleId: vehicle?.id,
418+
});
419+
acc.damages.push(...damages);
420+
acc.images.push(...images);
421+
acc.inspections.push(mappedInspection);
422+
acc.parts.push(...parts);
423+
acc.renderedOutputs.push(...renderedOutputs);
424+
if (vehicle) {
425+
acc.vehicles.push(vehicle);
426+
}
427+
acc.pricings.push(...pricings);
428+
429+
return acc;
430+
}, state);
431+
}
432+
377433
export function mapApiInspectionGet(
378434
response: ApiInspectionGet,
379435
thumbnailDomain: string,
@@ -568,3 +624,65 @@ export function mapApiInspectionPost(options: CreateInspectionOptions): ApiInspe
568624
},
569625
};
570626
}
627+
628+
interface PaginationRequestParams {
629+
/**
630+
* The number of inspections fetched.
631+
*
632+
* @default 100
633+
*/
634+
limit?: number;
635+
/**
636+
* The date (format ISO 8601) of inspection created or the inspection id.
637+
*/
638+
before?: string;
639+
/**
640+
* The date (format ISO 8601) of inspection created.
641+
*/
642+
after?: string;
643+
/**
644+
* The order of the pagination.
645+
*
646+
* @default SortOrder.DESC
647+
*/
648+
paginationOrder?: SortOrder;
649+
}
650+
651+
/**
652+
* Options passed to the `getInspections` API request.
653+
*/
654+
export interface GetInspectionsOptions {
655+
/**
656+
* If true, only the total count of inspections will be returned.
657+
*
658+
* @default false
659+
*/
660+
isCount?: boolean;
661+
/**
662+
* The filter request parameters.
663+
*/
664+
filter?: Record<string, string | number>;
665+
/**
666+
* The pagination request parameters.
667+
*/
668+
pagination?: PaginationRequestParams;
669+
}
670+
671+
export function mapApiInspectionsUrlParamsGet(options: GetInspectionsOptions): string {
672+
const params = new URLSearchParams();
673+
let url = options.isCount ? '/count' : '';
674+
url = options.filter || options.pagination ? `${url}?` : url;
675+
676+
if (options.filter) {
677+
Object.entries(options.filter).forEach(([key, value]) => {
678+
params.append(key, value.toString());
679+
});
680+
}
681+
682+
if (options.pagination) {
683+
Object.entries(options.pagination).forEach(([key, value]) => {
684+
params.append(key, value.toString());
685+
});
686+
}
687+
return `${url}${params.toString()}`;
688+
}

packages/network/src/api/inspection/requests.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ import {
99
import { AdditionalData, ComplianceOptions, CreateInspectionOptions } from '@monkvision/types';
1010
import { Dispatch } from 'react';
1111
import { getDefaultOptions, MonkApiConfig } from '../config';
12-
import { ApiIdColumn, ApiInspectionGet } from '../models';
13-
import { mapApiInspectionGet, mapApiInspectionPost } from './mappers';
12+
import { ApiIdColumn, ApiInspectionGet, ApiInspectionsGet } from '../models';
13+
import {
14+
GetInspectionsOptions,
15+
mapApiInspectionGet,
16+
mapApiInspectionPost,
17+
mapApiInspectionsGet,
18+
mapApiInspectionsUrlParamsGet,
19+
} from './mappers';
1420
import { MonkApiResponse } from '../types';
1521

1622
/**
@@ -143,3 +149,27 @@ export async function updateAdditionalData(
143149
body,
144150
};
145151
}
152+
153+
/**
154+
* Fetch the details of multiple inspections.
155+
*
156+
* @param options The options of the request.
157+
* @param config The API config.
158+
* @param [dispatch] Optional MonkState dispatch function that you can pass if you want this request to handle React
159+
* state management for you.
160+
*/
161+
export async function getInspections(
162+
options: GetInspectionsOptions,
163+
config: MonkApiConfig,
164+
dispatch?: Dispatch<MonkGotOneInspectionAction>,
165+
): Promise<MonkApiResponse | MonkApiResponse<GetInspectionResponse, ApiInspectionsGet>> {
166+
const kyOptions = getDefaultOptions(config);
167+
const response = await ky.get(`inspections${mapApiInspectionsUrlParamsGet(options)}`, kyOptions);
168+
const body = await response.json<ApiInspectionsGet>();
169+
const entities = mapApiInspectionsGet(body, config.thumbnailDomain);
170+
dispatch?.({
171+
type: MonkActionType.GOT_ONE_INSPECTION,
172+
payload: entities,
173+
});
174+
return { entities, response, body };
175+
}

packages/network/src/api/models/inspection.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SortOrder } from '@monkvision/types';
12
import type { ApiAdditionalData } from './common';
23
import type { ApiDamages } from './damage';
34
import type { ApiImagePost, ApiImages } from './image';
@@ -29,6 +30,37 @@ export interface ApiInspectionGet {
2930
wheel_analysis?: ApiWheelAnalysis;
3031
}
3132

33+
interface ApiData
34+
extends Pick<
35+
ApiInspectionGet,
36+
'id' | 'additional_data' | 'images' | 'damages' | 'pricing' | 'parts' | 'vehicle'
37+
> {
38+
pdf_url?: string;
39+
}
40+
41+
interface ApiPaginationParams {
42+
limit?: number;
43+
before?: string;
44+
after?: string;
45+
pagination_order?: SortOrder;
46+
}
47+
48+
interface ApiCursors {
49+
before?: Pick<ApiPaginationParams, 'before'>;
50+
after?: Pick<ApiPaginationParams, 'after'>;
51+
next?: ApiPaginationParams;
52+
previous?: ApiPaginationParams;
53+
}
54+
55+
interface ApiPagination {
56+
cursors: ApiCursors;
57+
}
58+
59+
export interface ApiInspectionsGet {
60+
data: ApiData[];
61+
paging: ApiPagination;
62+
}
63+
3264
export interface ApiDamageSeverity {
3365
output_format: ApiBusinessClients;
3466
}

packages/network/src/api/react.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ export function useMonkApi(config: MonkApiConfig) {
5656
* @param options The options of the request.
5757
*/
5858
getInspection: reactify(MonkApi.getInspection, config, dispatch, handleError),
59+
/**
60+
* Fetch multiple inspection.
61+
*
62+
* @param options The options of the request.
63+
*/
64+
getInspections: reactify(MonkApi.getInspections, config, dispatch, handleError),
5965
/**
6066
* Create a new inspection with the given options. See the `CreateInspectionOptions` interface for more details.
6167
*

packages/network/test/api/inspection/requests.test.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const mockInspection: Inspection = {
2828
parts: [],
2929
tasks: [],
3030
};
31+
const mockUrlParams = 'test-url-params';
3132

3233
jest.mock('../../../src/api/config', () => ({
3334
getDefaultOptions: jest.fn(() => ({ prefixUrl: 'getDefaultOptionsTest' })),
@@ -37,12 +38,26 @@ jest.mock('../../../src/api/inspection/mappers', () => ({
3738
inspections: [mockInspection] as unknown as Inspection[],
3839
parts: [],
3940
})),
41+
mapApiInspectionsGet: jest.fn(() => ({
42+
inspections: [mockInspection] as unknown as Inspection[],
43+
parts: [],
44+
})),
4045
mapApiInspectionPost: jest.fn(() => ({ test: 'ok-ok-ok' })),
46+
mapApiInspectionsUrlParamsGet: jest.fn(() => mockUrlParams),
4147
}));
4248

4349
import { getDefaultOptions } from '../../../src/api/config';
44-
import { createInspection, getInspection, updateAdditionalData } from '../../../src/api/inspection';
45-
import { mapApiInspectionGet, mapApiInspectionPost } from '../../../src/api/inspection/mappers';
50+
import {
51+
createInspection,
52+
getInspection,
53+
getInspections,
54+
updateAdditionalData,
55+
} from '../../../src/api/inspection';
56+
import {
57+
mapApiInspectionGet,
58+
mapApiInspectionPost,
59+
mapApiInspectionsGet,
60+
} from '../../../src/api/inspection/mappers';
4661

4762
const apiConfig = {
4863
apiDomain: 'apiDomain',
@@ -133,4 +148,30 @@ describe('Inspection requests', () => {
133148
});
134149
});
135150
});
151+
152+
describe('getInspections request', () => {
153+
it('should make the proper API call and map the resulting response', async () => {
154+
const dispatch = jest.fn();
155+
const result = await getInspections({ filter: { test: 'test' } }, apiConfig, dispatch);
156+
const response = await (ky.get as jest.Mock).mock.results[0].value;
157+
const body = await response.json();
158+
159+
expect(mapApiInspectionsGet).toHaveBeenCalledWith(body, apiConfig.thumbnailDomain);
160+
const entities = (mapApiInspectionsGet as jest.Mock).mock.results[0].value;
161+
expect(getDefaultOptions).toHaveBeenCalledWith(apiConfig);
162+
expect(ky.get).toHaveBeenCalledWith(
163+
`inspections${mockUrlParams}`,
164+
getDefaultOptions(apiConfig),
165+
);
166+
expect(dispatch).toHaveBeenCalledWith({
167+
type: MonkActionType.GOT_ONE_INSPECTION,
168+
payload: entities,
169+
});
170+
expect(result).toEqual({
171+
entities,
172+
response,
173+
body,
174+
});
175+
});
176+
});
136177
});

packages/network/test/api/react.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ jest.mock('../../src/api/api', () => ({
77
updatePricing: jest.fn(() => Promise.resolve({ test: 'updatePricing' })),
88
createDamage: jest.fn(() => Promise.resolve({ test: 'createDamage' })),
99
deleteDamage: jest.fn(() => Promise.resolve({ test: 'deleteDamage' })),
10+
getInspections: jest.fn(() => Promise.resolve({ test: 'getInspections' })),
1011
},
1112
}));
1213

@@ -96,6 +97,16 @@ describe('Monk API React utilities', () => {
9697
expect(requestMock).toHaveBeenCalledWith(param, config, dispatchMock);
9798
requestResultMock = await requestMock.mock.results[0].value;
9899
expect(resultMock).toBe(requestResultMock);
100+
101+
dispatchMock.mockClear();
102+
103+
param = 'test-getInspections';
104+
resultMock = await (result.current.getInspections as any)(param);
105+
requestMock = MonkApi.getInspections as jest.Mock;
106+
expect(requestMock).toHaveBeenCalledWith(param, config, dispatchMock);
107+
requestResultMock = await requestMock.mock.results[0].value;
108+
expect(resultMock).toBe(requestResultMock);
109+
99110
unmount();
100111
});
101112

packages/types/src/state/inspection.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export interface Inspection extends MonkEntity {
4444
* The details about the cost of the vehicle reparations using the PricingV2 API if it was requested.
4545
*/
4646
pricings?: string[];
47+
/**
48+
* The URL of the PDF report generated for this inspection.
49+
*/
50+
pdfUrl?: string;
4751
/**
4852
* Additional data added during the creation of the inspection.
4953
*/

packages/types/src/state/vehicle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export enum MileageUnit {
1010
}
1111

1212
/**
13-
* An object containing all the information abou t a vehicle that is being inspected during an inspection.
13+
* An object containing all the information about a vehicle that is being inspected during an inspection.
1414
*/
1515
export interface Vehicle extends MonkEntity {
1616
/**

0 commit comments

Comments
 (0)