18219: Replaces properties form on collection panel.
[arvados-workbench2.git] / src / store / resources / resources-actions.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { unionize, ofType, UnionOf } from 'common/unionize';
6 import { extractUuidKind, Resource, ResourceWithProperties } from 'models/resource';
7 import { Dispatch } from 'redux';
8 import { RootState } from 'store/store';
9 import { ServiceRepository } from 'services/services';
10 import { getResourceService } from 'services/services';
11 import { addProperty, deleteProperty } from 'lib/resource-properties';
12 import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
13 import { getResource } from './resources';
14 import { TagProperty } from 'models/tag';
15
16 export const resourcesActions = unionize({
17     SET_RESOURCES: ofType<Resource[]>(),
18     DELETE_RESOURCES: ofType<string[]>()
19 });
20
21 export type ResourcesAction = UnionOf<typeof resourcesActions>;
22
23 export const updateResources = (resources: Resource[]) => resourcesActions.SET_RESOURCES(resources);
24
25 export const deleteResources = (resources: string[]) => resourcesActions.DELETE_RESOURCES(resources);
26
27 export const loadResource = (uuid: string, showErrors?: boolean) =>
28     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
29         try {
30             const kind = extractUuidKind(uuid);
31             const service = getResourceService(kind)(services);
32             if (service) {
33                 const resource = await service.get(uuid, showErrors);
34                 dispatch<any>(updateResources([resource]));
35                 return resource;
36             }
37         } catch {}
38         return undefined;
39     };
40
41 export const deleteResourceProperty = (uuid: string, key: string, value: string) =>
42     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
43         const { resources } = getState();
44
45         const rsc = getResource(uuid)(resources) as ResourceWithProperties;
46         if (!rsc) { return; }
47
48         const kind = extractUuidKind(uuid);
49         const service = getResourceService(kind)(services);
50         if (!service) { return; }
51
52         const properties = Object.assign({}, rsc.properties);
53
54         try {
55             let updatedRsc = await service.update(
56                 uuid, {
57                     properties: deleteProperty(properties, key, value),
58                 });
59             updatedRsc = {...rsc, ...updatedRsc};
60             dispatch<any>(updateResources([updatedRsc]));
61             dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Property has been successfully deleted.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
62         } catch (e) {
63             dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.errors[0], hideDuration: 2000, kind: SnackbarKind.ERROR }));
64         }
65     };
66
67 export const createResourceProperty = (data: TagProperty) =>
68     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
69         const { uuid } = data;
70         const { resources } = getState();
71
72         const rsc = getResource(uuid)(resources) as ResourceWithProperties;
73         if (!rsc) { return; }
74
75         const kind = extractUuidKind(uuid);
76         const service = getResourceService(kind)(services);
77         if (!service) { return; }
78
79         try {
80             const key = data.keyID || data.key;
81             const value = data.valueID || data.value;
82             const properties = Object.assign({}, rsc.properties);
83             let updatedRsc = await service.update(
84                 rsc.uuid, {
85                     properties: addProperty(properties, key, value),
86                 }
87             );
88             updatedRsc = {...rsc, ...updatedRsc};
89             dispatch<any>(updateResources([updatedRsc]));
90             dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Property has been successfully added.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
91         } catch (e) {
92             const errorMsg = e.errors && e.errors.length > 0 ? e.errors[0] : "Error while adding property";
93             dispatch(snackbarActions.OPEN_SNACKBAR({ message: errorMsg, hideDuration: 2000, kind: SnackbarKind.ERROR }));
94         }
95     };