1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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 import { change, formValueSelector } from 'redux-form';
16 import { ResourcePropertiesFormData } from 'views-components/resource-properties-form/resource-properties-form';
18 export const resourcesActions = unionize({
19 SET_RESOURCES: ofType<Resource[]>(),
20 DELETE_RESOURCES: ofType<string[]>()
23 export type ResourcesAction = UnionOf<typeof resourcesActions>;
25 export const updateResources = (resources: Resource[]) => resourcesActions.SET_RESOURCES(resources);
27 export const deleteResources = (resources: string[]) => resourcesActions.DELETE_RESOURCES(resources);
29 export const loadResource = (uuid: string, showErrors?: boolean) =>
30 async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
32 const kind = extractUuidKind(uuid);
33 const service = getResourceService(kind)(services);
35 const resource = await service.get(uuid, showErrors);
36 dispatch<any>(updateResources([resource]));
43 export const deleteResourceProperty = (uuid: string, key: string, value: string) =>
44 async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
45 const { resources } = getState();
47 const rsc = getResource(uuid)(resources) as ResourceWithProperties;
50 const kind = extractUuidKind(uuid);
51 const service = getResourceService(kind)(services);
52 if (!service) { return; }
54 const properties = Object.assign({}, rsc.properties);
57 let updatedRsc = await service.update(
59 properties: deleteProperty(properties, key, value),
61 updatedRsc = {...rsc, ...updatedRsc};
62 dispatch<any>(updateResources([updatedRsc]));
63 dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Property has been successfully deleted.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
65 dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.errors[0], hideDuration: 2000, kind: SnackbarKind.ERROR }));
69 export const createResourceProperty = (data: TagProperty) =>
70 async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
71 const { uuid } = data;
72 const { resources } = getState();
74 const rsc = getResource(uuid)(resources) as ResourceWithProperties;
77 const kind = extractUuidKind(uuid);
78 const service = getResourceService(kind)(services);
79 if (!service) { return; }
82 const key = data.keyID || data.key;
83 const value = data.valueID || data.value;
84 const properties = Object.assign({}, rsc.properties);
85 let updatedRsc = await service.update(
87 properties: addProperty(properties, key, value),
90 updatedRsc = {...rsc, ...updatedRsc};
91 dispatch<any>(updateResources([updatedRsc]));
92 dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Property has been successfully added.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
94 const errorMsg = e.errors && e.errors.length > 0 ? e.errors[0] : "Error while adding property";
95 dispatch(snackbarActions.OPEN_SNACKBAR({ message: errorMsg, hideDuration: 2000, kind: SnackbarKind.ERROR }));
99 export const addPropertyToResourceForm = (data: ResourcePropertiesFormData, formName: string) =>
100 (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
101 const properties = { ...formValueSelector(formName)(getState(), 'properties') };
102 const key = data.keyID || data.key;
103 const value = data.valueID || data.value;
107 addProperty(properties, key, value)));
110 export const removePropertyFromResourceForm = (key: string, value: string, formName: string) =>
111 (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
112 const properties = { ...formValueSelector(formName)(getState(), 'properties') };
116 deleteProperty(properties, key, value)));