refs #master Merge branch 'origin/master' into 13828-trash-view
[arvados-workbench2.git] / src / store / project / project-action.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4 import { default as unionize, ofType, UnionOf } from "unionize";
5
6 import { ProjectResource } from "~/models/project";
7 import { Dispatch } from "redux";
8 import { FilterBuilder } from "~/common/api/filter-builder";
9 import { RootState } from "../store";
10 import { checkPresenceInFavorites } from "../favorites/favorites-actions";
11 import { ServiceRepository } from "~/services/services";
12 import { projectPanelActions } from "~/store/project-panel/project-panel-action";
13 import { updateDetails } from "~/store/details-panel/details-panel-action";
14 import { snackbarActions } from "~/store/snackbar/snackbar-actions";
15 import { trashPanelActions } from "~/store/trash-panel/trash-panel-action";
16 import { sidePanelActions } from "~/store/side-panel/side-panel-action";
17 import { SidePanelId } from "~/store/side-panel/side-panel-reducer";
18
19 export const projectActions = unionize({
20     OPEN_PROJECT_CREATOR: ofType<{ ownerUuid: string }>(),
21     CLOSE_PROJECT_CREATOR: ofType<{}>(),
22     CREATE_PROJECT: ofType<Partial<ProjectResource>>(),
23     CREATE_PROJECT_SUCCESS: ofType<ProjectResource>(),
24     OPEN_PROJECT_UPDATER: ofType<{ uuid: string}>(),
25     CLOSE_PROJECT_UPDATER: ofType<{}>(),
26     UPDATE_PROJECT_SUCCESS: ofType<ProjectResource>(),
27     REMOVE_PROJECT: ofType<string>(),
28     PROJECTS_REQUEST: ofType<string>(),
29     PROJECTS_SUCCESS: ofType<{ projects: ProjectResource[], parentItemId?: string }>(),
30     TOGGLE_PROJECT_TREE_ITEM_OPEN: ofType<{ itemId: string, open?: boolean, recursive?: boolean }>(),
31     TOGGLE_PROJECT_TREE_ITEM_ACTIVE: ofType<{ itemId: string, active?: boolean, recursive?: boolean }>(),
32     RESET_PROJECT_TREE_ACTIVITY: ofType<string>()
33 }, {
34     tag: 'type',
35     value: 'payload'
36 });
37
38 export const PROJECT_FORM_NAME = 'projectEditDialog';
39
40 export const getProjectList = (parentUuid: string = '') =>
41     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
42         dispatch(projectActions.PROJECTS_REQUEST(parentUuid));
43         return services.projectService.list({
44             filters: new FilterBuilder()
45                 .addEqual("ownerUuid", parentUuid)
46                 .getFilters()
47         }).then(({ items: projects }) => {
48             dispatch(projectActions.PROJECTS_SUCCESS({ projects, parentItemId: parentUuid }));
49             dispatch<any>(checkPresenceInFavorites(projects.map(project => project.uuid)));
50             return projects;
51         });
52     };
53
54 export const createProject = (project: Partial<ProjectResource>) =>
55     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
56         const { ownerUuid } = getState().projects.creator;
57         const projectData = { ownerUuid, ...project };
58         dispatch(projectActions.CREATE_PROJECT(projectData));
59         return services.projectService
60             .create(projectData)
61             .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project)));
62     };
63
64 export const updateProject = (project: Partial<ProjectResource>) =>
65     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
66         const { uuid } = getState().projects.updater;
67         return services.projectService
68             .update(uuid, project)
69             .then(project => {
70                 dispatch(projectActions.UPDATE_PROJECT_SUCCESS(project));
71                 dispatch(projectPanelActions.REQUEST_ITEMS());
72                 dispatch<any>(getProjectList(project.ownerUuid));
73                 dispatch<any>(updateDetails(project));
74             });
75     };
76
77 export const toggleProjectTrashed = (resource: { uuid: string; name: string, isTrashed?: boolean, ownerUuid?: string }) =>
78     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<any> => {
79         dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Working..." }));
80         if (resource.isTrashed) {
81             return services.groupsService.untrash(resource.uuid).then(() => {
82                 dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
83                     dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(SidePanelId.PROJECTS));
84                     dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
85                 });
86                 dispatch(trashPanelActions.REQUEST_ITEMS());
87                 dispatch(snackbarActions.CLOSE_SNACKBAR());
88                 dispatch(snackbarActions.OPEN_SNACKBAR({
89                     message: "Restored from trash",
90                     hideDuration: 2000
91                 }));
92             });
93         } else {
94             return services.groupsService.trash(resource.uuid).then(() => {
95                 dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
96                     dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
97                 });
98                 dispatch(snackbarActions.CLOSE_SNACKBAR());
99                 dispatch(snackbarActions.OPEN_SNACKBAR({
100                     message: "Added to trash",
101                     hideDuration: 2000
102                 }));
103             });
104         }
105     };
106
107 export type ProjectAction = UnionOf<typeof projectActions>;