18559: Add empty user profile page for 404
[arvados-workbench2.git] / src / store / user-profile / user-profile-actions.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4 import { RootState } from "store/store";
5 import { Dispatch } from 'redux';
6 import { initialize, reset } from "redux-form";
7 import { ServiceRepository } from "services/services";
8 import { bindDataExplorerActions } from "store/data-explorer/data-explorer-action";
9 import { propertiesActions } from 'store/properties/properties-actions';
10 import { getProperty } from 'store/properties/properties';
11 import { snackbarActions, SnackbarKind } from "store/snackbar/snackbar-actions";
12 import { updateResources } from "store/resources/resources-actions";
13 import { dialogActions } from "store/dialog/dialog-actions";
14
15 export const USER_PROFILE_PANEL_ID = 'userProfilePanel';
16 export const USER_PROFILE_FORM = 'userProfileForm';
17 export const DEACTIVATE_DIALOG = 'deactivateDialog';
18 export const SETUP_DIALOG = 'setupDialog';
19 export const IS_PROFILE_INACCESSIBLE = 'isProfileInaccessible';
20
21 export const UserProfileGroupsActions = bindDataExplorerActions(USER_PROFILE_PANEL_ID);
22
23 export const getCurrentUserProfilePanelUuid = getProperty<string>(USER_PROFILE_PANEL_ID);
24 export const getUserProfileIsInaccessible = getProperty<boolean>(IS_PROFILE_INACCESSIBLE);
25
26 export const loadUserProfilePanel = (userUuid?: string) =>
27   async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
28     // Reset isInacessible to ensure error screen is hidden
29     dispatch(propertiesActions.SET_PROPERTY({ key: IS_PROFILE_INACCESSIBLE, value: false }));
30     // Get user uuid from route or use current user uuid
31     const uuid = userUuid || getState().auth.user?.uuid;
32     if (uuid) {
33       await dispatch(propertiesActions.SET_PROPERTY({ key: USER_PROFILE_PANEL_ID, value: uuid }));
34       try {
35         const user = await services.userService.get(uuid, false);
36         dispatch(initialize(USER_PROFILE_FORM, user));
37         dispatch(updateResources([user]));
38         dispatch(UserProfileGroupsActions.REQUEST_ITEMS());
39       } catch (e) {
40         if (e.status === 404) {
41           await dispatch(propertiesActions.SET_PROPERTY({ key: IS_PROFILE_INACCESSIBLE, value: true }));
42           dispatch(reset(USER_PROFILE_FORM));
43         } else {
44           dispatch(snackbarActions.OPEN_SNACKBAR({
45             message: 'Could not load user profile',
46             kind: SnackbarKind.ERROR
47           }));
48         }
49       }
50     }
51   }
52
53 export const saveEditedUser = (resource: any) =>
54   async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
55       try {
56           const user = await services.userService.update(resource.uuid, resource);
57           dispatch(updateResources([user]));
58           dispatch(initialize(USER_PROFILE_FORM, user));
59           dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Profile has been updated.", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
60       } catch (e) {
61           dispatch(snackbarActions.OPEN_SNACKBAR({
62               message: "Could not update profile",
63               kind: SnackbarKind.ERROR,
64           }));
65       }
66   };
67
68 export const openDeactivateDialog = (uuid: string) =>
69   (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
70     dispatch(dialogActions.OPEN_DIALOG({
71       id: DEACTIVATE_DIALOG,
72       data: {
73           title: 'Deactivate user',
74           text: 'Are you sure you want to deactivate this user?',
75           confirmButtonLabel: 'Deactvate',
76           uuid
77       }
78   }));
79 }
80
81 export const openSetupDialog = (uuid: string) =>
82   (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
83     dispatch(dialogActions.OPEN_DIALOG({
84       id: SETUP_DIALOG,
85       data: {
86           title: 'Setup user',
87           text: 'Are you sure you want to setup this user?',
88           confirmButtonLabel: 'Confirm',
89           uuid
90       }
91   }));
92 }
93
94 export const setup = (uuid: string) =>
95     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
96         try {
97             const resources = await services.userService.setup(uuid);
98             dispatch(updateResources(resources.items));
99             dispatch(snackbarActions.OPEN_SNACKBAR({ message: "User has been setup", hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
100         } catch (e) {
101             dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.message, hideDuration: 2000, kind: SnackbarKind.ERROR }));
102         } finally {
103             dispatch(dialogActions.CLOSE_DIALOG({ id: SETUP_DIALOG }));
104         }
105
106     };
107
108 export const unsetup = (uuid: string) =>
109     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
110         try {
111           const user = await services.userService.unsetup(uuid);
112           dispatch(updateResources([user]));
113           dispatch(snackbarActions.OPEN_SNACKBAR({
114               message: "User has been deactivated.",
115               hideDuration: 2000,
116               kind: SnackbarKind.SUCCESS
117           }));
118         } catch (e) {
119           dispatch(snackbarActions.OPEN_SNACKBAR({
120               message: "Could not deactivate user",
121               kind: SnackbarKind.ERROR,
122           }));
123         }
124     };