1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
4 import { default as unionize, ofType, UnionOf } from "unionize";
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";
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>()
38 export const PROJECT_FORM_NAME = 'projectEditDialog';
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)
47 }).then(({ items: projects }) => {
48 dispatch(projectActions.PROJECTS_SUCCESS({ projects, parentItemId: parentUuid }));
49 dispatch<any>(checkPresenceInFavorites(projects.map(project => project.uuid)));
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
61 .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project)));
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)
70 dispatch(projectActions.UPDATE_PROJECT_SUCCESS(project));
71 dispatch(projectPanelActions.REQUEST_ITEMS());
72 dispatch<any>(getProjectList(project.ownerUuid));
73 dispatch<any>(updateDetails(project));
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 }));
86 dispatch(trashPanelActions.REQUEST_ITEMS());
87 dispatch(snackbarActions.CLOSE_SNACKBAR());
88 dispatch(snackbarActions.OPEN_SNACKBAR({
89 message: "Restored from trash",
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 }));
98 dispatch(snackbarActions.CLOSE_SNACKBAR());
99 dispatch(snackbarActions.OPEN_SNACKBAR({
100 message: "Added to trash",
107 export type ProjectAction = UnionOf<typeof projectActions>;