69c4bac3ac894926d81d17193d56f5c4a887be25
[arvados-workbench2.git] / src / services / common-service / common-resource-service.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { AxiosInstance } from "axios";
6 import * as _ from "lodash";
7 import { Resource } from "src/models/resource";
8 import { ApiActions } from "services/api/api-actions";
9 import { CommonService } from "services/common-service/common-service";
10
11 export enum CommonResourceServiceError {
12     UNIQUE_NAME_VIOLATION = 'UniqueNameViolation',
13     OWNERSHIP_CYCLE = 'OwnershipCycle',
14     MODIFYING_CONTAINER_REQUEST_FINAL_STATE = 'ModifyingContainerRequestFinalState',
15     NAME_HAS_ALREADY_BEEN_TAKEN = 'NameHasAlreadyBeenTaken',
16     UNKNOWN = 'Unknown',
17     NONE = 'None'
18 }
19
20 export class CommonResourceService<T extends Resource> extends CommonService<T> {
21     constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions, readOnlyFields: string[] = []) {
22         super(serverApi, resourceType, actions, readOnlyFields.concat([
23             'uuid',
24             'etag',
25             'kind'
26         ]));
27     }
28
29     create(data?: Partial<T>) {
30         let payload: any;
31         if (data !== undefined) {
32             this.readOnlyFields.forEach( field => delete data[field] );
33             payload = {
34                 [this.resourceType.slice(0, -1)]: CommonService.mapKeys(_.snakeCase)(data),
35             };
36         }
37         return super.create(payload);
38     }
39
40     update(uuid: string, data: Partial<T>) {
41         let payload: any;
42         if (data !== undefined) {
43             this.readOnlyFields.forEach( field => delete data[field] );
44             payload = {
45                 [this.resourceType.slice(0, -1)]: CommonService.mapKeys(_.snakeCase)(data),
46             };
47         }
48         return super.update(uuid, payload);
49     }
50 }
51
52 export const getCommonResourceServiceError = (errorResponse: any) => {
53     if ('errors' in errorResponse && 'errorToken' in errorResponse) {
54         const error = errorResponse.errors.join('');
55         switch (true) {
56             case /UniqueViolation/.test(error):
57                 return CommonResourceServiceError.UNIQUE_NAME_VIOLATION;
58             case /ownership cycle/.test(error):
59                 return CommonResourceServiceError.OWNERSHIP_CYCLE;
60             case /Mounts cannot be modified in state 'Final'/.test(error):
61                 return CommonResourceServiceError.MODIFYING_CONTAINER_REQUEST_FINAL_STATE;
62             case /Name has already been taken/.test(error):
63                 return CommonResourceServiceError.NAME_HAS_ALREADY_BEEN_TAKEN;
64             default:
65                 return CommonResourceServiceError.UNKNOWN;
66         }
67     }
68     return CommonResourceServiceError.NONE;
69 };
70
71