15781: Adds multi-value property support for projects.
[arvados-workbench2.git] / src / store / collection-panel / collection-panel-action.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Dispatch } from "redux";
6 import { loadCollectionFiles } from "./collection-panel-files/collection-panel-files-actions";
7 import { CollectionResource } from '~/models/collection';
8 import { collectionPanelFilesAction } from "./collection-panel-files/collection-panel-files-actions";
9 import { createTree } from "~/models/tree";
10 import { RootState } from "~/store/store";
11 import { ServiceRepository } from "~/services/services";
12 import { TagProperty } from "~/models/tag";
13 import { snackbarActions } from "../snackbar/snackbar-actions";
14 import { resourcesActions } from "~/store/resources/resources-actions";
15 import { unionize, ofType, UnionOf } from '~/common/unionize';
16 import { SnackbarKind } from '~/store/snackbar/snackbar-actions';
17 import { navigateTo } from '~/store/navigation/navigation-action';
18 import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
19 import { deleteProperty, addProperty } from "~/lib/resource-properties";
20
21 export const collectionPanelActions = unionize({
22     SET_COLLECTION: ofType<CollectionResource>(),
23     LOAD_COLLECTION: ofType<{ uuid: string }>(),
24     LOAD_COLLECTION_SUCCESS: ofType<{ item: CollectionResource }>()
25 });
26
27 export type CollectionPanelAction = UnionOf<typeof collectionPanelActions>;
28
29 export const COLLECTION_TAG_FORM_NAME = 'collectionTagForm';
30
31 export const loadCollectionPanel = (uuid: string) =>
32     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
33         dispatch(collectionPanelActions.LOAD_COLLECTION({ uuid }));
34         dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES({ files: createTree() }));
35         const collection = await services.collectionService.get(uuid);
36         dispatch(loadDetailsPanel(collection.uuid));
37         dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: collection }));
38         dispatch(resourcesActions.SET_RESOURCES([collection]));
39         dispatch<any>(loadCollectionFiles(collection.uuid));
40         return collection;
41     };
42
43 export const createCollectionTag = (data: TagProperty) =>
44     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
45         const item = getState().collectionPanel.item;
46         const uuid = item ? item.uuid : '';
47         try {
48             if (item) {
49                 const key = data.keyID || data.key;
50                 const value = data.valueID || data.value;
51                 item.properties = addProperty(item.properties, key, value);
52                 const updatedCollection = await services.collectionService.update(
53                     uuid, {
54                         properties: {...item.properties}
55                     }
56                 );
57                 item.properties = updatedCollection.properties;
58                 dispatch(resourcesActions.SET_RESOURCES([updatedCollection]));
59                 dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Tag has been successfully added.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
60                 return updatedCollection;
61             }
62             return;
63         } catch (e) {
64             dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.errors[0], hideDuration: 2000, kind: SnackbarKind.ERROR }));
65             return;
66         }
67     };
68
69 export const navigateToProcess = (uuid: string) =>
70     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
71         try {
72             await services.containerRequestService.get(uuid);
73             dispatch<any>(navigateTo(uuid));
74         } catch {
75             dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'This process does not exist!', hideDuration: 2000, kind: SnackbarKind.ERROR }));
76         }
77     };
78
79 export const deleteCollectionTag = (key: string, value: string) =>
80     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
81         const item = getState().collectionPanel.item;
82         const uuid = item ? item.uuid : '';
83         try {
84             if (item) {
85                 item.properties = deleteProperty(item.properties, key, value);
86
87                 const updatedCollection = await services.collectionService.update(
88                     uuid, {
89                         properties: {...item.properties}
90                     }
91                 );
92                 dispatch(resourcesActions.SET_RESOURCES([updatedCollection]));
93                 dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Tag has been successfully deleted.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
94                 return updatedCollection;
95             }
96             return;
97         } catch (e) {
98             dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.errors[0], hideDuration: 2000, kind: SnackbarKind.ERROR }));
99             return;
100         }
101     };