From a7c19ba56bb72420bb1f4428dcad6ba737f412a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patr=C3=ADcia=20Dias?= Date: Thu, 23 Feb 2023 16:53:56 +0000 Subject: [PATCH 1/6] fix: removed unnused imports --- backend/src/modules/auth/auth.module.ts | 1 - backend/src/modules/auth/services/register.auth.service.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/backend/src/modules/auth/auth.module.ts b/backend/src/modules/auth/auth.module.ts index ac50123f4..70a346f5e 100644 --- a/backend/src/modules/auth/auth.module.ts +++ b/backend/src/modules/auth/auth.module.ts @@ -1,5 +1,4 @@ import { userRepository } from 'src/modules/users/users.providers'; -import { UserRepository } from './../users/repository/user.repository'; import { mongooseBoardUserModule } from './../../infrastructure/database/mongoose.module'; import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; diff --git a/backend/src/modules/auth/services/register.auth.service.ts b/backend/src/modules/auth/services/register.auth.service.ts index eb358d5d6..c80bca9ad 100644 --- a/backend/src/modules/auth/services/register.auth.service.ts +++ b/backend/src/modules/auth/services/register.auth.service.ts @@ -1,5 +1,4 @@ import { UserRepositoryInterface } from './../../users/repository/user.repository.interface'; -import { userRepository } from 'src/modules/users/users.providers'; import { GetTokenAuthService } from 'src/modules/auth/interfaces/services/get-token.auth.service.interface'; import { BOARD_USER_NOT_FOUND, INSERT_FAILED } from 'src/libs/exceptions/messages'; import { BadRequestException, Inject, Injectable } from '@nestjs/common'; From b9795abc637a0093f7f0e0138768933d49c9b0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patr=C3=ADcia=20Dias?= Date: Thu, 23 Feb 2023 17:17:09 +0000 Subject: [PATCH 2/6] feat: pasrticipants page as a guest user --- .../Board/RegularBoard/ParticipantsList/index.tsx | 9 ++++++--- .../Board/RegularBoard/ReagularHeader/index.tsx | 2 +- .../Teams/CreateTeam/ListMembersDialog/index.tsx | 2 +- frontend/src/pages/boards/[boardId]/participants.tsx | 9 ++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx index 4ceca9bc7..690330479 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx @@ -5,6 +5,7 @@ import { ScrollableContent } from '@/components/Boards/MyBoards/styles'; import { boardParticipantsState } from '@/store/board/atoms/board.atom'; import { BoardUserRoles } from '@/utils/enums/board.user.roles'; import { useSession } from 'next-auth/react'; +import { getGuestUserCookies } from '@/utils/getGuestUserCookies'; import ParticipantsLayout from './ParticipantsLayout'; import ParticipantCard from './ParticipantCard.tsx'; @@ -12,10 +13,12 @@ const ParticipantsList = () => { const boardParticipants = useRecoilValue(boardParticipantsState); const { data: session } = useSession(); + const userId = session ? session.user.id : getGuestUserCookies().user; + const isResponsible = !!boardParticipants.find( - (boardUser) => - boardUser.user._id === session?.user.id && boardUser.role === BoardUserRoles.RESPONSIBLE, + (boardUser) => boardUser.user._id === userId && boardUser.role === BoardUserRoles.RESPONSIBLE, ); + const isSAdmin = !!session?.user.isSAdmin; return ( @@ -31,7 +34,7 @@ const ParticipantsList = () => { diff --git a/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx b/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx index 8185d20db..a7e9b2dc5 100644 --- a/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx @@ -30,7 +30,7 @@ interface Props { } const RegularBoardHeader = ({ isParticipantsPage }: Props) => { - const { data: session } = useSession(); + const { data: session } = useSession({ required: false }); // Atoms const boardData = useRecoilValue(boardInfoState); diff --git a/frontend/src/components/Teams/CreateTeam/ListMembersDialog/index.tsx b/frontend/src/components/Teams/CreateTeam/ListMembersDialog/index.tsx index 5742372fd..bf38d8374 100644 --- a/frontend/src/components/Teams/CreateTeam/ListMembersDialog/index.tsx +++ b/frontend/src/components/Teams/CreateTeam/ListMembersDialog/index.tsx @@ -20,7 +20,7 @@ type ListMembersDialogProps = { const ListMembersDialog = React.memo( ({ usersList, isOpen, setIsOpen, saveUsers, title, btnTitle }) => { - const { data: session } = useSession({ required: true }); + const { data: session } = useSession({ required: false }); const [searchMember, setSearchMember] = useState(''); const [usersChecked, setUsersChecked] = useState(usersList); diff --git a/frontend/src/pages/boards/[boardId]/participants.tsx b/frontend/src/pages/boards/[boardId]/participants.tsx index b5b072632..b5644aa70 100644 --- a/frontend/src/pages/boards/[boardId]/participants.tsx +++ b/frontend/src/pages/boards/[boardId]/participants.tsx @@ -16,7 +16,6 @@ import { BoardUserRoles } from '@/utils/enums/board.user.roles'; import { ToastStateEnum } from '@/utils/enums/toast-types'; import { QueryClient, dehydrate, useQuery } from '@tanstack/react-query'; import { GetServerSideProps } from 'next'; -import { useSession } from 'next-auth/react'; import React, { Suspense, useCallback, useEffect } from 'react'; import { SetterOrUpdater, useRecoilState, useSetRecoilState } from 'recoil'; @@ -41,10 +40,9 @@ export const sortParticipantsList = ( }; const BoardParticipants = () => { - const { data: session } = useSession({ required: false }); const setToastState = useSetRecoilState(toastState); const [boardParticipants, setBoardParticipants] = useRecoilState(boardParticipantsState); - const setRecoilBoard = useSetRecoilState(boardInfoState); + const [recoilBoard, setRecoilBoard] = useRecoilState(boardInfoState); // Hooks const { @@ -93,8 +91,7 @@ const BoardParticipants = () => { handleMembersList(); }, [handleMembersList]); - if (!session) return null; - return ( + return recoilBoard ? ( }> @@ -107,6 +104,8 @@ const BoardParticipants = () => { + ) : ( + ); }; From 5c2465abd963f96d504a7241ff13cab12784b70c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patr=C3=ADcia=20Dias?= Date: Thu, 23 Feb 2023 17:31:52 +0000 Subject: [PATCH 3/6] refactor: regular board with team has participants page --- .../RegularBoard/ParticipantsList/index.tsx | 3 +- .../ReagularHeader/HeaderParticipants.tsx | 2 +- .../RegularBoard/ReagularHeader/index.tsx | 99 +++---------------- 3 files changed, 17 insertions(+), 87 deletions(-) diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx index 690330479..97a46e1f8 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx @@ -13,7 +13,8 @@ const ParticipantsList = () => { const boardParticipants = useRecoilValue(boardParticipantsState); const { data: session } = useSession(); - const userId = session ? session.user.id : getGuestUserCookies().user; + // User Id + const userId = getGuestUserCookies() ? getGuestUserCookies().user : session?.user.id; const isResponsible = !!boardParticipants.find( (boardUser) => boardUser.user._id === userId && boardUser.role === BoardUserRoles.RESPONSIBLE, diff --git a/frontend/src/components/Board/RegularBoard/ReagularHeader/HeaderParticipants.tsx b/frontend/src/components/Board/RegularBoard/ReagularHeader/HeaderParticipants.tsx index 35565af57..97edfd491 100644 --- a/frontend/src/components/Board/RegularBoard/ReagularHeader/HeaderParticipants.tsx +++ b/frontend/src/components/Board/RegularBoard/ReagularHeader/HeaderParticipants.tsx @@ -44,7 +44,7 @@ const HeaderParticipants = ({ isParticipantsPage }: Props) => { - Board Creator + Responsibles { const isRegularBoardWithNoTeam = !team; + // User id + const userId = getGuestUserCookies() ? getGuestUserCookies().user : session?.user.id; + // Set breadcrumbs const breadcrumbItems: BreadcrumbType = isParticipantsPage ? [ @@ -101,92 +105,17 @@ const RegularBoardHeader = ({ isParticipantsPage }: Props) => { - {!isEmpty(teamUsers) && ( - - - - - - {team?.name} - - - + + {isParticipantsPage ? ( + + ) : ( + + + - {!isEmpty( - teamUsers.filter((user: TeamUser) => user.role === TeamUserRoles.ADMIN), - ) && ( - <> - - - - - Team admins - - - - - )} - {!isEmpty( - boardData.board.team?.users.filter( - (user: TeamUser) => user.role === TeamUserRoles.STAKEHOLDER, - ), - ) && ( - <> - - - - - Stakeholders - - - - - )} - - - )} - - {isRegularBoardWithNoTeam && ( - - {isParticipantsPage ? ( - - ) : ( - - - - - - )} - - )} + + )} + From fea3c3f72b9a806d3dcf0531beadacc008c3ac02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patr=C3=ADcia=20Dias?= Date: Thu, 23 Feb 2023 18:19:45 +0000 Subject: [PATCH 4/6] feat: avoid boards without responsibles or with only guest user responsibles --- .../auth/services/register.auth.service.ts | 5 +++-- .../boards/services/get.board.service.ts | 2 +- .../modules/boards/utils/populate-board.ts | 4 ++-- .../src/modules/users/dto/guest.user.dto.ts | 6 +++++- .../ParticipantCard.tsx/index.tsx | 13 +++++++++++- .../RegularBoard/ParticipantsList/index.tsx | 16 +++++++++++++++ .../RegularBoard/ReagularHeader/index.tsx | 20 +------------------ .../ConfigurationSwitch.tsx | 7 ++++++- frontend/src/types/user/user.ts | 1 + 9 files changed, 47 insertions(+), 27 deletions(-) diff --git a/backend/src/modules/auth/services/register.auth.service.ts b/backend/src/modules/auth/services/register.auth.service.ts index c80bca9ad..e9fac7ac3 100644 --- a/backend/src/modules/auth/services/register.auth.service.ts +++ b/backend/src/modules/auth/services/register.auth.service.ts @@ -54,7 +54,7 @@ export default class RegisterAuthServiceImpl implements RegisterAuthService { throw new BadRequestException(BOARD_USER_NOT_FOUND); } - const { _id, firstName, lastName } = userFound.user as User; + const { _id, firstName, lastName, isAnonymous } = userFound.user as User; return { role: userFound.role, @@ -63,7 +63,8 @@ export default class RegisterAuthServiceImpl implements RegisterAuthService { user: { _id: String(_id), firstName, - lastName + lastName, + isAnonymous } }; } diff --git a/backend/src/modules/boards/services/get.board.service.ts b/backend/src/modules/boards/services/get.board.service.ts index 2b639c9b6..223516bf7 100644 --- a/backend/src/modules/boards/services/get.board.service.ts +++ b/backend/src/modules/boards/services/get.board.service.ts @@ -152,7 +152,7 @@ export default class GetBoardServiceImpl implements GetBoardServiceInterface { select: 'user role -board', populate: { path: 'user', - select: '_id firstName email lastName' + select: '_id firstName email lastName isAnonymous' } }) .lean({ virtuals: true }) diff --git a/backend/src/modules/boards/utils/populate-board.ts b/backend/src/modules/boards/utils/populate-board.ts index 86e6f3f69..5355adf84 100644 --- a/backend/src/modules/boards/utils/populate-board.ts +++ b/backend/src/modules/boards/utils/populate-board.ts @@ -4,7 +4,7 @@ export const BoardDataPopulate: PopulateOptions[] = [ { path: 'users', select: 'user role -board votesCount', - populate: { path: 'user', select: 'firstName email lastName _id' } + populate: { path: 'user', select: 'firstName email lastName _id isAnonymous' } }, { path: 'team', @@ -49,7 +49,7 @@ export const GetBoardDataPopulate: PopulateOptions[] = [ { path: 'users', select: 'user role -board votesCount', - populate: { path: 'user', select: 'firstName email lastName _id' } + populate: { path: 'user', select: 'firstName email lastName _id isAnonymous' } }, { path: 'team', diff --git a/backend/src/modules/users/dto/guest.user.dto.ts b/backend/src/modules/users/dto/guest.user.dto.ts index bf60ad807..bbc42e467 100644 --- a/backend/src/modules/users/dto/guest.user.dto.ts +++ b/backend/src/modules/users/dto/guest.user.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsMongoId, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { IsBoolean, IsMongoId, IsNotEmpty, IsOptional, IsString } from 'class-validator'; export default class GuestUserDto { @ApiProperty() @@ -18,4 +18,8 @@ export default class GuestUserDto { @IsOptional() @IsString() lastName?: string; + + @IsOptional() + @IsBoolean() + isAnonymous?: boolean; } diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx index 9e6adc121..e849df39f 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx @@ -20,11 +20,19 @@ type CardBodyProps = { isCurrentUserResponsible: boolean; isCurrentUserSAdmin: boolean; isMemberCurrentUser: boolean; + responibleToggleDisabled: boolean; isOpen?: boolean; }; const ParticipantCard = React.memo( - ({ member, isCurrentUserResponsible, isCurrentUserSAdmin, isMemberCurrentUser, isOpen }) => { + ({ + member, + isCurrentUserResponsible, + isCurrentUserSAdmin, + isMemberCurrentUser, + isOpen, + responibleToggleDisabled, + }) => { const { addAndRemoveBoardParticipants: { mutate }, } = useParticipants(); @@ -100,6 +108,9 @@ const ParticipantCard = React.memo( isChecked={isMemberResponsible} text="" title="Responsible" + disabled={ + responibleToggleDisabled && isMemberCurrentUser && !isCurrentUserSAdmin + } /> )} diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx index 97a46e1f8..1e8eae411 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx @@ -22,6 +22,21 @@ const ParticipantsList = () => { const isSAdmin = !!session?.user.isSAdmin; + const responsiblesList = boardParticipants.filter( + (boardUser) => boardUser.role === BoardUserRoles.RESPONSIBLE, + ); + + const responsibleGuestUsers = responsiblesList.filter((boardUser) => boardUser.user.isAnonymous); + + const responsibleSignedUpUsers = responsiblesList.filter( + (boardUser) => !boardUser.user.isAnonymous, + ); + + const condition = + responsiblesList.length < 2 || + responsibleGuestUsers.length === responsiblesList.length || + responsibleSignedUpUsers.length < 2; + return ( @@ -38,6 +53,7 @@ const ParticipantsList = () => { isMemberCurrentUser={member.user._id === userId} isCurrentUserResponsible={isResponsible} isCurrentUserSAdmin={isSAdmin} + responibleToggleDisabled={condition} /> ))} diff --git a/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx b/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx index 5bd9b69f6..70bae4ffe 100644 --- a/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ReagularHeader/index.tsx @@ -1,21 +1,14 @@ -import { useSession } from 'next-auth/react'; import { useRecoilValue } from 'recoil'; import Breadcrumb from '@/components/Primitives/Breadcrumb'; import Icon from '@/components/Primitives/Icon'; import LogoIcon from '@/components/icons/Logo'; import Flex from '@/components/Primitives/Flex'; -import Separator from '@/components/Primitives/Separator'; import Text from '@/components/Primitives/Text'; import Tooltip from '@/components/Primitives/Tooltip'; import { boardInfoState } from '@/store/board/atoms/board.atom'; import { BreadcrumbType } from '@/types/board/Breadcrumb'; -import { TeamUser } from '@/types/team/team.user'; -import { TeamUserRoles } from '@/utils/enums/team.user.roles'; -import isEmpty from '@/utils/isEmpty'; import Link from 'next/link'; -import { StyledBoardTitle } from '@/components/CardBoard/CardBody/CardTitle/partials/Title/styles'; -import AvatarGroup from '@/components/Primitives/Avatar/AvatarGroup'; import { MergeIconContainer, RecurrentIconContainer, @@ -24,28 +17,17 @@ import { TitleSection, } from '../../SplitBoard/Header/styles'; import HeaderParticipants from './HeaderParticipants'; -import { getGuestUserCookies } from '@/utils/getGuestUserCookies'; interface Props { isParticipantsPage?: boolean; } const RegularBoardHeader = ({ isParticipantsPage }: Props) => { - const { data: session } = useSession({ required: false }); - // Atoms const boardData = useRecoilValue(boardInfoState); // Get Board Info - const { title, recurrent, users, team, isSubBoard, submitedAt, _id } = boardData.board; - - // Get Team users - const teamUsers = team?.users ? team.users : []; - - const isRegularBoardWithNoTeam = !team; - - // User id - const userId = getGuestUserCookies() ? getGuestUserCookies().user : session?.user.id; + const { title, recurrent, isSubBoard, submitedAt, _id } = boardData.board; // Set breadcrumbs const breadcrumbItems: BreadcrumbType = isParticipantsPage diff --git a/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx b/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx index 2a002881b..125de7f4c 100644 --- a/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx +++ b/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx @@ -37,7 +37,12 @@ const ConfigurationSwitchSettings = ({ ) : ( - + )} diff --git a/frontend/src/types/user/user.ts b/frontend/src/types/user/user.ts index 08eb2978e..2aa434bb3 100644 --- a/frontend/src/types/user/user.ts +++ b/frontend/src/types/user/user.ts @@ -17,6 +17,7 @@ export interface User { isSAdmin: boolean; joinedAt: string; providerAccountCreatedAt?: string; + isAnonymous?: boolean; } export interface UseUserType { From 92c7c92a6355e1e134daf8b394e388aa1d029ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 23 Feb 2023 18:53:36 +0000 Subject: [PATCH 5/6] fix: fix condition to disable toggle responsible on participants page --- .../ParticipantsList/ParticipantCard.tsx/index.tsx | 9 ++++----- .../Board/RegularBoard/ParticipantsList/index.tsx | 4 ++-- .../ConfigurationSettings/ConfigurationSwitch.tsx | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx index e849df39f..58a4d2328 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx @@ -20,7 +20,7 @@ type CardBodyProps = { isCurrentUserResponsible: boolean; isCurrentUserSAdmin: boolean; isMemberCurrentUser: boolean; - responibleToggleDisabled: boolean; + haveInvalidNumberOfResponsibles: boolean; isOpen?: boolean; }; @@ -31,7 +31,7 @@ const ParticipantCard = React.memo( isCurrentUserSAdmin, isMemberCurrentUser, isOpen, - responibleToggleDisabled, + haveInvalidNumberOfResponsibles, }) => { const { addAndRemoveBoardParticipants: { mutate }, @@ -108,9 +108,8 @@ const ParticipantCard = React.memo( isChecked={isMemberResponsible} text="" title="Responsible" - disabled={ - responibleToggleDisabled && isMemberCurrentUser && !isCurrentUserSAdmin - } + disabledInfo="Select another responsible for the board" + disabled={haveInvalidNumberOfResponsibles && isMemberResponsible} /> )} diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx index 1e8eae411..13d6ed34a 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx @@ -32,7 +32,7 @@ const ParticipantsList = () => { (boardUser) => !boardUser.user.isAnonymous, ); - const condition = + const haveInvalidNumberOfResponsibles = responsiblesList.length < 2 || responsibleGuestUsers.length === responsiblesList.length || responsibleSignedUpUsers.length < 2; @@ -53,7 +53,7 @@ const ParticipantsList = () => { isMemberCurrentUser={member.user._id === userId} isCurrentUserResponsible={isResponsible} isCurrentUserSAdmin={isSAdmin} - responibleToggleDisabled={condition} + haveInvalidNumberOfResponsibles={haveInvalidNumberOfResponsibles} /> ))} diff --git a/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx b/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx index 125de7f4c..cfd1bde51 100644 --- a/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx +++ b/frontend/src/components/Board/Settings/partials/ConfigurationSettings/ConfigurationSwitch.tsx @@ -25,7 +25,7 @@ const ConfigurationSwitchSettings = ({ disabledInfo, }: Props) => ( - {disabledInfo ? ( + {disabledInfo && disabled ? ( Date: Fri, 24 Feb 2023 11:29:16 +0000 Subject: [PATCH 6/6] fix: avoided board with no responsible --- .../ParticipantsList/ParticipantCard.tsx/index.tsx | 12 +++++++++++- .../Board/RegularBoard/ParticipantsList/index.tsx | 8 ++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx index 58a4d2328..9616c77ff 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/ParticipantCard.tsx/index.tsx @@ -21,6 +21,7 @@ type CardBodyProps = { isCurrentUserSAdmin: boolean; isMemberCurrentUser: boolean; haveInvalidNumberOfResponsibles: boolean; + responsibleSignedUpUsers: BoardUser[]; isOpen?: boolean; }; @@ -32,6 +33,7 @@ const ParticipantCard = React.memo( isMemberCurrentUser, isOpen, haveInvalidNumberOfResponsibles, + responsibleSignedUpUsers, }) => { const { addAndRemoveBoardParticipants: { mutate }, @@ -69,6 +71,14 @@ const ParticipantCard = React.memo( const handleSelectFunction = (checked: boolean) => updateIsResponsibleStatus(checked); + let memberOnlySignedUpResponsible: boolean = false; + + if (haveInvalidNumberOfResponsibles) { + memberOnlySignedUpResponsible = !!responsibleSignedUpUsers.find( + (boardUser) => boardUser.user._id === member.user._id, + ); + } + return ( @@ -109,7 +119,7 @@ const ParticipantCard = React.memo( text="" title="Responsible" disabledInfo="Select another responsible for the board" - disabled={haveInvalidNumberOfResponsibles && isMemberResponsible} + disabled={memberOnlySignedUpResponsible && !isCurrentUserSAdmin} /> )} diff --git a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx index 13d6ed34a..4b5dc04db 100644 --- a/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx +++ b/frontend/src/components/Board/RegularBoard/ParticipantsList/index.tsx @@ -26,16 +26,11 @@ const ParticipantsList = () => { (boardUser) => boardUser.role === BoardUserRoles.RESPONSIBLE, ); - const responsibleGuestUsers = responsiblesList.filter((boardUser) => boardUser.user.isAnonymous); - const responsibleSignedUpUsers = responsiblesList.filter( (boardUser) => !boardUser.user.isAnonymous, ); - const haveInvalidNumberOfResponsibles = - responsiblesList.length < 2 || - responsibleGuestUsers.length === responsiblesList.length || - responsibleSignedUpUsers.length < 2; + const haveInvalidNumberOfResponsibles = responsibleSignedUpUsers.length < 2; return ( @@ -54,6 +49,7 @@ const ParticipantsList = () => { isCurrentUserResponsible={isResponsible} isCurrentUserSAdmin={isSAdmin} haveInvalidNumberOfResponsibles={haveInvalidNumberOfResponsibles} + responsibleSignedUpUsers={responsibleSignedUpUsers} /> ))}