import { Box, Button, Icon, Modal, Accordion, AccordionItem, ModalHeader, ModalTitle, ModalClose, ModalContent, ModalFooter, ModalFooterControllers, } from '@rocket.chat/fuselage'; import { TextInput, ToggleSwitch, Field, FieldGroup, FieldLabel, FieldRow, FieldError, FieldHint } from '@rocket.chat/fuselage-forms'; import { useEndpoint, usePermission, usePermissionWithScopedRoles, useSetting, useToastMessageDispatch, useTranslation, } from '@rocket.chat/ui-contexts'; import type { ComponentProps } from 'react'; import { useId, memo, useEffect, useMemo } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { useEncryptedRoomDescription } from './useEncryptedRoomDescription'; import UserAutoCompleteMultiple from '../../../components/UserAutoCompleteMultiple'; import { useCreateChannelTypePermission } from '../../../hooks/useCreateChannelTypePermission'; import { useGoToRoom } from '../../../views/room/hooks/useGoToRoom'; type CreateTeamModalInputs = { name: string; topic: string; isPrivate: boolean; readOnly: boolean; encrypted: boolean; broadcast: boolean; members?: string[]; }; export type CreateTeamModalProps = { onClose: () => void; onSuccess?: (rid: string) => void | Promise }; const CreateTeamModal = ({ onClose, onSuccess }: CreateTeamModalProps) => { const t = useTranslation(); const e2eEnabled = useSetting('E2E_Enable'); const e2eEnabledForPrivateByDefault = useSetting('E2E_Enabled_Default_PrivateRooms') && e2eEnabled; const e2eEnforcedForPrivate = Boolean(useSetting('E2E_Force_Encryption_For_Private_Rooms')) && Boolean(e2eEnabled); const namesValidation = useSetting('UTF8_Channel_Names_Validation'); const allowSpecialNames = useSetting('UI_Allow_room_names_with_special_chars'); const canSetReadOnly = usePermissionWithScopedRoles('set-readonly', ['owner']); const dispatchToastMessage = useToastMessageDispatch(); const canCreateTeam = usePermission('create-team'); const checkTeamNameExists = useEndpoint('GET', '/v1/rooms.nameExists'); const createTeamAction = useEndpoint('POST', '/v1/teams.create'); const teamNameRegex = useMemo(() => { if (allowSpecialNames) { return null; } return new RegExp(`^${namesValidation}$`); }, [allowSpecialNames, namesValidation]); const canOnlyCreateOneType = useCreateChannelTypePermission(); const validateTeamName = async (name: string): Promise => { if (!name) { return; } if (teamNameRegex && !teamNameRegex?.test(name)) { return t('Name_cannot_have_special_characters'); } const { exists } = await checkTeamNameExists({ roomName: name }); if (exists) { return t('Teams_Errors_Already_exists', { name }); } }; const { control, handleSubmit, setValue, watch, formState: { errors, isSubmitting }, } = useForm({ defaultValues: { name: '', topic: '', isPrivate: canOnlyCreateOneType ? canOnlyCreateOneType === 'p' : true, readOnly: false, encrypted: Boolean(e2eEnforcedForPrivate || e2eEnabledForPrivateByDefault), broadcast: false, members: [], }, }); const { isPrivate, broadcast, readOnly, encrypted } = watch(); useEffect(() => { if (!isPrivate) { setValue('encrypted', false); } else if (e2eEnforcedForPrivate) { setValue('encrypted', true); } setValue('readOnly', broadcast); }, [watch, setValue, broadcast, isPrivate, e2eEnforcedForPrivate]); const readOnlyDisabled = broadcast || !canSetReadOnly; const canChangeEncrypted = isPrivate && e2eEnabled && !e2eEnforcedForPrivate; const getEncryptedHint = useEncryptedRoomDescription('team'); const goToRoom = useGoToRoom(); const handleCreateTeam = async ({ name, members, isPrivate, readOnly, topic, broadcast, encrypted, }: CreateTeamModalInputs): Promise => { const params = { name, members, type: isPrivate ? 1 : 0, room: { readOnly, extraData: { topic, broadcast, encrypted, }, }, }; try { const { team } = await createTeamAction(params); dispatchToastMessage({ type: 'success', message: t('Team_has_been_created') }); goToRoom(team.roomId); void onSuccess?.(team.roomId); onClose(); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } }; const createTeamFormId = useId(); return ( ) => ( )} > {t('Teams_New_Title')} {t('Teams_new_description')} {t('Teams_New_Name_Label')} validateTeamName(value), }} render={({ field }) => ( } error={errors.name?.message} aria-required='true' /> )} /> {errors?.name && {errors.name.message}} {!allowSpecialNames && {t('No_spaces_or_special_characters')}} {t('Topic')} } /> {t('Displayed_next_to_name')} {t('Teams_New_Add_members_Label')} ( )} /> {t('Teams_New_Private_Label')} ( )} /> {isPrivate ? t('People_can_only_join_by_being_invited') : t('Anyone_can_access')} {t('Security_and_permissions')} {t('Teams_New_Encrypted_Label')} ( )} /> {getEncryptedHint({ isPrivate, encrypted })} {t('Teams_New_Read_only_Label')} ( )} /> {readOnly ? t('Read_only_field_hint_enabled', { roomType: 'team' }) : t('Anyone_can_send_new_messages')} {t('Teams_New_Broadcast_Label')} } /> {broadcast && {t('Teams_New_Broadcast_Description')}} ); }; export default memo(CreateTeamModal);