Skip to content

Commit

Permalink
[FIX] Members selection field on creating team modal (#25871)
Browse files Browse the repository at this point in the history
<!-- This is a pull request template, you do not need to uncomment or remove the comments, they won't show up in the PR text. -->

<!-- Your Pull Request name should start with one of the following tags
  [NEW] For new features
  [IMPROVE] For an improvement (performance or little improvements) in existing features
  [FIX] For bug fixes that affect the end-user
  [BREAK] For pull requests including breaking changes
  Chore: For small tasks
  Doc: For documentation
-->

<!-- Checklist!!! If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code. 
  - I have read the Contributing Guide - https://github.com/RocketChat/Rocket.Chat/blob/develop/.github/CONTRIBUTING.md#contributing-to-rocketchat doc
  - I have signed the CLA - https://cla-assistant.io/RocketChat/Rocket.Chat
  - Lint and unit tests pass locally with my changes
  - I have added tests that prove my fix is effective or that my feature works (if applicable)
  - I have added necessary documentation (if applicable)
  - Any dependent changes have been merged and published in downstream modules
-->

## Proposed changes (including videos or screenshots)
<!-- CHANGELOG -->
<!--
  Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.
  If it fixes a bug or resolves a feature request, be sure to link to that issue below.
  This description will appear in the release notes if we accept the contribution.
-->
- Fix: add members breaking when searching users

![image](https://user-images.githubusercontent.com/27704687/121788070-b792f700-cba0-11eb-92b9-5833e1213c74.png)

<!-- END CHANGELOG -->

## Issue(s)
<!-- Link the issues being closed by or related to this PR. For example, you can use #594 if this PR closes issue number 594 -->

## Steps to test or reproduce
<!-- Mention how you would reproduce the bug if not mentioned on the issue page already. Also mention which screens are going to have the changes if applicable -->

## Further comments
<!-- If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... -->


Co-authored-by: Pierre Lehnen <55164754+pierre-lehnen-rc@users.noreply.github.com>
  • Loading branch information
dougfabris and pierre-lehnen-rc authored Jun 20, 2022
1 parent acb74f1 commit 9a41c4f
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 293 deletions.
211 changes: 8 additions & 203 deletions apps/meteor/client/views/teams/CreateTeamModal/CreateTeamModal.tsx
Original file line number Diff line number Diff line change
@@ -1,207 +1,13 @@
import type { IUser } from '@rocket.chat/core-typings';
import { Box, Modal, ButtonGroup, Button, TextInput, Field, ToggleSwitch, FieldGroup } from '@rocket.chat/fuselage';
import { useMutableCallback, useDebouncedCallback, useAutoFocus } from '@rocket.chat/fuselage-hooks';
import { useSetting, usePermission, useMethod, useTranslation } from '@rocket.chat/ui-contexts';
import React, { FC, memo, useCallback, useEffect, useMemo, useState } from 'react';
import { useAutoFocus } from '@rocket.chat/fuselage-hooks';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React, { memo, ReactElement } from 'react';

import { useEndpointActionExperimental } from '../../../hooks/useEndpointActionExperimental';
import { useForm } from '../../../hooks/useForm';
import { goToRoomById } from '../../../lib/utils/goToRoomById';
import UserAutoCompleteMultiple from '../../../components/UserAutoCompleteMultiple';
import TeamNameInput from './TeamNameInput';
import UsersInput from './UsersInput';
import { useCreateTeamModalState } from './useCreateTeamModalState';

type CreateTeamModalState = {
name: any;
nameError: any;
onChangeName: any;
description: any;
onChangeDescription: any;
type: any;
onChangeType: any;
readOnly: any;
canChangeReadOnly: any;
onChangeReadOnly: any;
encrypted: any;
canChangeEncrypted: any;
onChangeEncrypted: any;
broadcast: any;
onChangeBroadcast: any;
members: any;
onChangeMembers: any;
hasUnsavedChanges: any;
isCreateButtonEnabled: any;
onCreate: any;
};

const useCreateTeamModalState = (onClose: () => void): CreateTeamModalState => {
const e2eEnabled = useSetting('E2E_Enable');
const e2eEnabledForPrivateByDefault = useSetting('E2E_Enabled_Default_PrivateRooms');
const namesValidation = useSetting('UTF8_Channel_Names_Validation');
const allowSpecialNames = useSetting('UI_Allow_room_names_with_special_chars');

const { values, handlers, hasUnsavedChanges } = useForm({
members: [],
name: '',
description: '',
type: true,
readOnly: false,
encrypted: e2eEnabledForPrivateByDefault ?? false,
broadcast: false,
});

const { name, description, type, readOnly, broadcast, encrypted, members } = values as {
name: string;
description: string;
type: boolean;
readOnly: boolean;
broadcast: boolean;
encrypted: boolean;
members: Exclude<IUser['username'], undefined>[];
};

const { handleMembers, handleEncrypted, handleType, handleBroadcast, handleReadOnly } = handlers;

const t = useTranslation();

const teamNameRegex = useMemo(() => {
if (allowSpecialNames) {
return null;
}

return new RegExp(`^${namesValidation}$`);
}, [allowSpecialNames, namesValidation]);

const [nameError, setNameError] = useState<string>();

const teamNameExists = useMethod('roomNameExists');

const checkName = useDebouncedCallback(
async (name: string) => {
setNameError(undefined);

if (!hasUnsavedChanges) {
return;
}

if (!name || name.length === 0) {
setNameError(t('Field_required'));
return;
}

if (teamNameRegex && !teamNameRegex.test(name)) {
setNameError(t('error-invalid-name'));
return;
}

const isNotAvailable = await teamNameExists(name);
if (isNotAvailable) {
setNameError(t('Teams_Errors_team_name', { name }));
}
},
230,
[name],
);

useEffect(() => {
checkName(name);
}, [checkName, name]);

const canChangeReadOnly = !broadcast;

const canChangeEncrypted = type && !broadcast && e2eEnabled && !e2eEnabledForPrivateByDefault;

const onChangeName = handlers.handleName;

const onChangeDescription = handlers.handleDescription;

const onChangeType = useMutableCallback((value) => {
handleEncrypted(!value);
return handleType(value);
});

const onChangeReadOnly = handlers.handleReadOnly;

const onChangeEncrypted = handlers.handleEncrypted;

const onChangeBroadcast = useCallback(
(value) => {
handleEncrypted(!value);
handleReadOnly(value);
return handleBroadcast(value);
},
[handleBroadcast, handleEncrypted, handleReadOnly],
);

const onChangeMembers = useCallback(
(value, action) => {
if (!action) {
if (members.includes(value)) {
return;
}
return handleMembers([...members, value]);
}
handleMembers(members.filter((current) => current !== value));
},
[handleMembers, members],
);

const canSave = hasUnsavedChanges && !nameError;
const canCreateTeam = usePermission('create-team');
const isCreateButtonEnabled = canSave && canCreateTeam;

const createTeam = useEndpointActionExperimental('POST', '/v1/teams.create');

const onCreate = useCallback(async () => {
const params = {
name,
members,
type: type ? 1 : 0,
room: {
readOnly,
extraData: {
description,
broadcast,
encrypted,
},
},
};

const data = await createTeam(params);

goToRoomById(data.team.roomId);

onClose();
}, [name, members, type, readOnly, description, broadcast, encrypted, createTeam, onClose]);

return {
name,
nameError,
onChangeName,
description,
onChangeDescription,
type,
onChangeType,
readOnly,
canChangeReadOnly,
onChangeReadOnly,
encrypted,
canChangeEncrypted,
onChangeEncrypted,
broadcast,
onChangeBroadcast,
members,
onChangeMembers,
hasUnsavedChanges,
isCreateButtonEnabled,
onCreate,
};
};

type CreateTeamModalProps = {
onClose: () => void;
};

const CreateTeamModal: FC<CreateTeamModalProps> = ({ onClose }) => {
const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => {
const {
name,
nameError,
Expand All @@ -226,14 +32,13 @@ const CreateTeamModal: FC<CreateTeamModalProps> = ({ onClose }) => {
} = useCreateTeamModalState(onClose);

const t = useTranslation();

const focusRef = useAutoFocus<HTMLInputElement>();

return (
<Modal>
<Modal.Header>
<Modal.Title>{t('Teams_New_Title')}</Modal.Title>
<Modal.Close onClick={onClose} />
<Modal.Close title={t('Close')} onClick={onClose} />
</Modal.Header>
<Modal.Content>
<FieldGroup>
Expand Down Expand Up @@ -310,7 +115,7 @@ const CreateTeamModal: FC<CreateTeamModalProps> = ({ onClose }) => {
({t('optional')})
</Box>
</Field.Label>
<UsersInput value={members} onChange={onChangeMembers} />
<UserAutoCompleteMultiple value={members} onChange={onChangeMembers} />
</Field>
</FieldGroup>
</Modal.Content>
Expand Down
90 changes: 0 additions & 90 deletions apps/meteor/client/views/teams/CreateTeamModal/UsersInput.tsx

This file was deleted.

Loading

0 comments on commit 9a41c4f

Please sign in to comment.