diff --git a/apps/meteor/client/views/admin/users/AdminUserCreated.tsx b/apps/meteor/client/views/admin/users/AdminUserCreated.tsx new file mode 100644 index 000000000000..f69a0911e0ac --- /dev/null +++ b/apps/meteor/client/views/admin/users/AdminUserCreated.tsx @@ -0,0 +1,32 @@ +import { Button, ButtonGroup, ContextualbarFooter } from '@rocket.chat/fuselage'; +import { useRouter, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { useCallback } from 'react'; + +import { ContextualbarScrollableContent } from '../../../components/Contextualbar'; + +const AdminUserCreated = ({ uid }: { uid: string }) => { + const t = useTranslation(); + const router = useRouter(); + + const goToUser = useCallback((id) => router.navigate(`/admin/users/info/${id}`), [router]); + + return ( + <> + + {t('You_have_created_one_user')} + + + + + + + + + ); +}; + +export default AdminUserCreated; diff --git a/apps/meteor/client/views/admin/users/AdminUserForm.tsx b/apps/meteor/client/views/admin/users/AdminUserForm.tsx index beff65ba56a2..09386a093e59 100644 --- a/apps/meteor/client/views/admin/users/AdminUserForm.tsx +++ b/apps/meteor/client/views/admin/users/AdminUserForm.tsx @@ -10,7 +10,6 @@ import { Icon, FieldGroup, ContextualbarFooter, - ButtonGroup, Button, Callout, } from '@rocket.chat/fuselage'; @@ -27,7 +26,7 @@ import { useTranslation, } from '@rocket.chat/ui-contexts'; import { useQuery, useMutation } from '@tanstack/react-query'; -import React, { useCallback, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { validateEmail } from '../../../../lib/emailValidator'; @@ -54,10 +53,12 @@ const getInitialValue = ({ data, defaultUserRoles, isSmtpEnabled, + isNewUserPage, }: { data?: Serialized; defaultUserRoles?: IUser['roles']; isSmtpEnabled?: boolean; + isNewUserPage?: boolean; }): userFormProps => ({ roles: data?.roles ?? defaultUserRoles, name: data?.name ?? '', @@ -67,8 +68,8 @@ const getInitialValue = ({ nickname: data?.nickname ?? '', email: (data?.emails?.length && data.emails[0].address) || '', verified: (data?.emails?.length && data.emails[0].verified) || false, - setRandomPassword: true, - setPasswordManually: false, + setRandomPassword: isNewUserPage, + setPasswordManually: !isNewUserPage, requirePasswordChange: data?.requirePasswordChange || false, customFields: data?.customFields ?? {}, statusText: data?.statusText ?? '', @@ -93,29 +94,32 @@ const UserForm = ({ userData, onReload, ...props }: AdminUserFormProps) => { const { data } = useSmtpQuery(); const isSmtpEnabled = data?.isSMTPConfigured; - const eventStats = useEndpointAction('POST', '/v1/statistics.telemetry'); - const updateUserAction = useEndpoint('POST', '/v1/users.update'); - const createUserAction = useEndpoint('POST', '/v1/users.create'); - - const getRoles = useEndpoint('GET', '/v1/roles.list'); - const { data: roleData, error: roleError } = useQuery(['roles'], async () => getRoles()); - - const availableRoles: SelectOption[] = roleData?.roles.map(({ _id, name, description }) => [_id, description || name]) || []; - - const goToUser = useCallback((id) => router.navigate(`/admin/users/info/${id}`), [router]); - const { control, watch, handleSubmit, - // reset, formState: { errors, isDirty }, setValue, + resetField, } = useForm({ - defaultValues: getInitialValue({ data: userData, defaultUserRoles, isSmtpEnabled }), + defaultValues: getInitialValue({ data: userData, defaultUserRoles, isSmtpEnabled, isNewUserPage: !userData?._id }), mode: 'onBlur', }); + useEffect(() => { + resetField('sendWelcomeEmail', { defaultValue: isSmtpEnabled }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isSmtpEnabled]); + + const eventStats = useEndpointAction('POST', '/v1/statistics.telemetry'); + const updateUserAction = useEndpoint('POST', '/v1/users.update'); + const createUserAction = useEndpoint('POST', '/v1/users.create'); + + const getRoles = useEndpoint('GET', '/v1/roles.list'); + const { data: roleData, error: roleError } = useQuery(['roles'], async () => getRoles()); + + const availableRoles: SelectOption[] = roleData?.roles.map(({ _id, name, description }) => [_id, description || name]) || []; + const { avatar, username, setRandomPassword, password } = watch(); const updateAvatar = useUpdateAvatar(avatar, userData?._id || ''); @@ -135,12 +139,12 @@ const UserForm = ({ userData, onReload, ...props }: AdminUserFormProps) => { const handleCreateUser = useMutation({ mutationFn: createUserAction, - onSuccess: async (data) => { + onSuccess: async ({ user: { _id } }) => { dispatchToastMessage({ type: 'success', message: t('User_created_successfully!') }); await eventStats({ params: [{ eventName: 'updateCounter', settingsId: 'Manual_Entry_User_Count' }], }); - goToUser(data.user._id); + router.navigate(`/admin/users/created/${_id}`); onReload(); }, onError: (error) => { @@ -194,7 +198,7 @@ const UserForm = ({ userData, onReload, ...props }: AdminUserFormProps) => { /> )} - {t('Manually_created_users_briefing')} + {!userData?._id && {t('Manually_created_users_briefing')}} {t('Email')} @@ -520,18 +524,9 @@ const UserForm = ({ userData, onReload, ...props }: AdminUserFormProps) => { - - {/* */} - - + ); diff --git a/apps/meteor/client/views/admin/users/AdminUsersPage.tsx b/apps/meteor/client/views/admin/users/AdminUsersPage.tsx index 1829766aa5cc..284e31561f81 100644 --- a/apps/meteor/client/views/admin/users/AdminUsersPage.tsx +++ b/apps/meteor/client/views/admin/users/AdminUsersPage.tsx @@ -8,6 +8,7 @@ import { useSeatsCap } from '../../../../ee/client/views/admin/users/useSeatsCap import { Contextualbar, ContextualbarHeader, ContextualbarTitle, ContextualbarClose } from '../../../components/Contextualbar'; import Page from '../../../components/Page'; import AdminInviteUsers from './AdminInviteUsers'; +import AdminUserCreated from './AdminUserCreated'; import AdminUserForm from './AdminUserForm'; import AdminUserFormWithData from './AdminUserFormWithData'; import AdminUserInfoWithData from './AdminUserInfoWithData'; @@ -90,7 +91,7 @@ const UsersPage = (): ReactElement => { {context === 'info' && t('User_Info')} {context === 'edit' && t('Edit_User')} - {context === 'new' && ( + {(context === 'new' || context === 'created') && ( <> {t('New_user')} @@ -102,6 +103,7 @@ const UsersPage = (): ReactElement => { {context === 'info' && id && } {context === 'edit' && id && } {context === 'new' && } + {context === 'created' && id && } {context === 'invite' && } )} diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index b1135a97a849..7d7440bdec82 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -307,6 +307,7 @@ "Add_files_from": "Add files from", "Add_manager": "Add manager", "Add_monitor": "Add monitor", + "Add_more_users": "Add more users", "Add_Reaction": "Add reaction", "Add_Role": "Add Role", "Add_Sender_To_ReplyTo": "Add Sender to Reply-To", @@ -5769,6 +5770,7 @@ "You_have_a_new_message": "You have a new message", "You_have_been_muted": "You have been muted and cannot speak in this room", "You_have_been_removed_from__roomName_": "You've been removed from the room {{roomName}}", + "You_have_created_one_user": "You’ve created 1 user", "You_have_joined_a_new_call_with": "You have joined a new call with", "You_have_n_codes_remaining": "You have {{number}} codes remaining.", "You_have_not_verified_your_email": "You have not verified your email.",