+
+
+
+
-
-
Add new users
-
-
-
-
+
Add new users
+
+
+
-
- >
+
+
);
};
diff --git a/src/modules/users/components/MultipleUsersModal/types.ts b/src/modules/users/components/MultipleUsersModal/types.ts
index 2a3a280..643f10c 100644
--- a/src/modules/users/components/MultipleUsersModal/types.ts
+++ b/src/modules/users/components/MultipleUsersModal/types.ts
@@ -1,5 +1,10 @@
+import { initialAppRoles } from 'src/components/UserModal/consts';
+
export type MultipleUsersModalProps = {
open: boolean;
onClose: () => void;
- onUpload: () => void;
+};
+
+export const initialMultipleUsersForm = {
+ appRoles: initialAppRoles,
};
diff --git a/src/modules/users/components/MultipleUsersModal/utils.ts b/src/modules/users/components/MultipleUsersModal/utils.ts
deleted file mode 100644
index 7934b5d..0000000
--- a/src/modules/users/components/MultipleUsersModal/utils.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { User } from 'src/services/users';
-
-export const csvFileToArray = (csvData: string) => {
- const csvRows = csvData.slice(csvData.indexOf('\n') + 1).split('\n');
-
- const array = csvRows.map((i) => {
- const values = i.split(',');
- const email = values[0];
- const name = values[1];
- return { email, name, app_roles: [], preferredUsername: '', status: '', id: '' } as User;
- });
-
- return array;
-};
diff --git a/src/services/users/hooks/use-users.ts b/src/services/users/hooks/use-users.ts
index 0e5dd35..f5079b8 100644
--- a/src/services/users/hooks/use-users.ts
+++ b/src/services/users/hooks/use-users.ts
@@ -7,6 +7,7 @@ import {
createUser,
deleteUser,
clearCurrentUser,
+ createBatchUsers,
} from '../redux';
import { getUserById, getUserModalLoading, getUserslLoading } from '../redux/selectors';
@@ -37,6 +38,10 @@ export function useUsers() {
return dispatch(createUser(data));
}
+ function createUsers(data: any) {
+ return dispatch(createBatchUsers(data));
+ }
+
function deleteUserById(id: string) {
return dispatch(deleteUser(id));
}
@@ -52,5 +57,6 @@ export function useUsers() {
createNewUser,
deleteUserById,
clearSelectedUser,
+ createUsers,
};
}
diff --git a/src/services/users/redux/actions.ts b/src/services/users/redux/actions.ts
index 7c35034..4ac3932 100644
--- a/src/services/users/redux/actions.ts
+++ b/src/services/users/redux/actions.ts
@@ -1,9 +1,15 @@
+import _ from 'lodash';
import { Dispatch } from 'redux';
import { showToast, ToastType } from 'src/common/util/show-toast';
import { State } from 'src/redux/types';
import { performApiCall } from 'src/services/api';
import { AuthActionTypes } from 'src/services/auth';
-import { transformRequestUser, transformUser } from '../transformations';
+import {
+ transformBatchResponse,
+ transformRequestMultipleUsers,
+ transformRequestUser,
+ transformUser,
+} from '../transformations';
export enum UserActionTypes {
FETCH_USERS = 'users/fetch_users',
@@ -13,6 +19,7 @@ export enum UserActionTypes {
DELETE_USER = 'users/delete_user',
SET_USER_MODAL_LOADING = 'users/user_modal_loading',
SET_USERS_LOADING = 'users/users_loading',
+ CREATE_BATCH_USERS = 'users/create_batch_users',
}
export const setUsersLoading = (isLoading: boolean) => (dispatch: Dispatch
) => {
@@ -154,6 +161,51 @@ export const deleteUser = (id: string) => async (dispatch: Dispatch) => {
dispatch(setUserModalLoading(false));
};
+export const createBatchUsers = (users: any) => async (dispatch: Dispatch) => {
+ dispatch(setUserModalLoading(true));
+
+ try {
+ const { data } = await performApiCall({
+ path: '/users-batch',
+ method: 'POST',
+ body: transformRequestMultipleUsers(users),
+ });
+
+ const responseData = transformBatchResponse(data);
+
+ dispatch({
+ type: UserActionTypes.CREATE_BATCH_USERS,
+ payload: responseData,
+ });
+
+ // show information about created users
+ const createdUsersNumber = _.size(responseData.createdUsers);
+ if (createdUsersNumber > 0) {
+ showToast(
+ `${_.size(responseData.createdUsers)} ${createdUsersNumber > 1 ? 'users' : 'user'} created successfully.`,
+ ToastType.Success,
+ );
+ }
+ const notCreatedUsersNumber = _.size(responseData.notCreatedUsers);
+ if (notCreatedUsersNumber > 0) {
+ showToast(
+ `${_.size(responseData.notCreatedUsers)}
+ ${notCreatedUsersNumber > 1 ? 'users' : 'user'} not created with
+ ${notCreatedUsersNumber > 1 ? 'emails' : 'email'}: \n${responseData.notCreatedUsers.join(',\n')}`,
+ ToastType.Error,
+ );
+ }
+
+ dispatch(fetchUsers());
+ } catch (err: any) {
+ dispatch(setUserModalLoading(false));
+ showToast(`${err}`, ToastType.Error);
+ throw err;
+ }
+
+ dispatch(setUserModalLoading(false));
+};
+
export const clearCurrentUser = () => (dispatch: Dispatch) => {
dispatch({
type: UserActionTypes.DELETE_USER,
diff --git a/src/services/users/redux/reducers.ts b/src/services/users/redux/reducers.ts
index 71ff2fa..2d02771 100644
--- a/src/services/users/redux/reducers.ts
+++ b/src/services/users/redux/reducers.ts
@@ -27,6 +27,7 @@ const usersReducer = (state: any = initialUsersState, action: any) => {
case UserActionTypes.FETCH_USER:
case UserActionTypes.UPDATE_USER:
case UserActionTypes.CREATE_USER:
+ case UserActionTypes.CREATE_BATCH_USERS:
return {
...state,
isModalVisible: false,
diff --git a/src/services/users/transformations.ts b/src/services/users/transformations.ts
index bc2bd05..65b869c 100644
--- a/src/services/users/transformations.ts
+++ b/src/services/users/transformations.ts
@@ -1,4 +1,5 @@
-import { AppRoles, User, UserRole } from './types';
+import _ from 'lodash';
+import { AppRoles, MultipleUsersData, User, UserRole } from './types';
const transformRoleById = (roleId: any): UserRole => {
switch (roleId) {
@@ -62,3 +63,30 @@ export const transformRequestUser = (data: Pick {
+ const csvRows = csvData.split('\n');
+
+ return _.map(csvRows, (row) => {
+ const values = row.split(',');
+ const email = values[0].trim();
+ const name = !_.isNil(values[1]) ? values[1].trim() : '';
+ return { email, name, app_roles: [] };
+ });
+};
+
+export const transformRequestMultipleUsers = (data: MultipleUsersData) => {
+ const batchUsers = extractUsersFromCsv(data.csvUserData);
+ return {
+ users: _.map(batchUsers, (user) =>
+ transformRequestUser({ app_roles: data.appRoles, name: user.name, email: user.email } as User),
+ ),
+ };
+};
+
+export const transformBatchResponse = (response: any): any => {
+ return {
+ createdUsers: response.created_users,
+ notCreatedUsers: response.not_created_users,
+ };
+};
diff --git a/src/services/users/types.ts b/src/services/users/types.ts
index f97f435..d22811c 100644
--- a/src/services/users/types.ts
+++ b/src/services/users/types.ts
@@ -29,3 +29,8 @@ export interface UserApiRequest {
name: string;
status: string;
}
+
+export interface MultipleUsersData {
+ csvUserData: string;
+ appRoles: AppRoles[];
+}