From 546044b28bc068317157228720478aa4211b0d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 2 Feb 2023 13:00:35 +0000 Subject: [PATCH 1/9] feat: return votes to users when column is deleted --- backend/src/modules/boards/boards.module.ts | 2 + .../controller/boards.controller.spec.ts | 4 ++ .../boards/controller/boards.controller.ts | 12 +--- .../modules/boards/dto/update-board.dto.ts | 8 ++- .../boards/services/create.board.service.ts | 9 ++- .../boards/services/update.board.service.ts | 72 ++++++++++++++++++- 6 files changed, 93 insertions(+), 14 deletions(-) diff --git a/backend/src/modules/boards/boards.module.ts b/backend/src/modules/boards/boards.module.ts index f400be662..40e24cd14 100644 --- a/backend/src/modules/boards/boards.module.ts +++ b/backend/src/modules/boards/boards.module.ts @@ -7,6 +7,7 @@ import { CommunicationModule } from 'src/modules/communication/communication.mod import { SchedulesModule } from 'src/modules/schedules/schedules.module'; import TeamsModule from 'src/modules/teams/teams.module'; import UsersModule from 'src/modules/users/users.module'; +import { VotesModule } from '../votes/votes.module'; import { createBoardApplication, createBoardService, @@ -23,6 +24,7 @@ import BoardsController from './controller/boards.controller'; imports: [ UsersModule, forwardRef(() => TeamsModule), + VotesModule, SchedulesModule, CommunicationModule, mongooseBoardModule, diff --git a/backend/src/modules/boards/controller/boards.controller.spec.ts b/backend/src/modules/boards/controller/boards.controller.spec.ts index 168c69a9d..7f1930974 100644 --- a/backend/src/modules/boards/controller/boards.controller.spec.ts +++ b/backend/src/modules/boards/controller/boards.controller.spec.ts @@ -12,6 +12,7 @@ import { updateBoardService } from 'src/modules/boards/boards.providers'; import BoardsController from 'src/modules/boards/controller/boards.controller'; +import { getCardService } from 'src/modules/cards/cards.providers'; import * as CommunicationsType from 'src/modules/communication/interfaces/types'; import { createSchedulesService, @@ -26,6 +27,7 @@ import { teamUserRepository, updateTeamService } from 'src/modules/teams/providers'; +import { deleteVoteService } from 'src/modules/votes/votes.providers'; describe('BoardsController', () => { let controller: BoardsController; @@ -52,6 +54,8 @@ describe('BoardsController', () => { teamRepository, teamUserRepository, updateTeamService, + deleteVoteService, + getCardService, { provide: getModelToken('User'), useValue: {} diff --git a/backend/src/modules/boards/controller/boards.controller.ts b/backend/src/modules/boards/controller/boards.controller.ts index 8745d54cb..d726506d9 100644 --- a/backend/src/modules/boards/controller/boards.controller.ts +++ b/backend/src/modules/boards/controller/boards.controller.ts @@ -235,16 +235,8 @@ export default class BoardsController { @BoardUser([BoardRoles.RESPONSIBLE, TeamRoles.ADMIN, TeamRoles.STAKEHOLDER]) @UseGuards(BoardUserGuard) @Put(':boardId') - async updateBoard(@Param() { boardId }: BaseParam, @Body() boardData: UpdateBoardDto) { - const board = await this.updateBoardApp.update(boardId, boardData); - - if (!board) throw new BadRequestException(UPDATE_FAILED); - - if (boardData.socketId) { - this.socketService.sendUpdatedBoard(boardId, boardData.socketId); - } - - return board; + updateBoard(@Param() { boardId }: BaseParam, @Body() boardData: UpdateBoardDto) { + return this.updateBoardApp.update(boardId, boardData); } @ApiOperation({ summary: 'Delete a specific board' }) diff --git a/backend/src/modules/boards/dto/update-board.dto.ts b/backend/src/modules/boards/dto/update-board.dto.ts index b955ff3cb..03cc85cca 100644 --- a/backend/src/modules/boards/dto/update-board.dto.ts +++ b/backend/src/modules/boards/dto/update-board.dto.ts @@ -1,5 +1,6 @@ import { PartialType } from '@nestjs/mapped-types'; -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; import { IsOptional } from 'class-validator'; import BoardUser from '../schemas/board.user.schema'; import BoardDto from './board.dto'; @@ -8,4 +9,9 @@ export class UpdateBoardDto extends PartialType(BoardDto) { @ApiPropertyOptional({ type: BoardUser, isArray: true }) @IsOptional() responsible?: BoardUser; + + @ApiProperty({ type: String, isArray: true }) + @IsOptional() + @Type(() => String) + deletedColumns?: string[]; } diff --git a/backend/src/modules/boards/services/create.board.service.ts b/backend/src/modules/boards/services/create.board.service.ts index 85feef496..1b24ece7d 100644 --- a/backend/src/modules/boards/services/create.board.service.ts +++ b/backend/src/modules/boards/services/create.board.service.ts @@ -144,7 +144,7 @@ export default class CreateBoardServiceImpl implements CreateBoardService { const { team, recurrent, maxUsers, slackEnable, users, dividedBoards } = boardData; const haveDividedBoards = dividedBoards.length > 0 ? true : false; - let newUsers = []; + const newUsers = []; const newBoard = await this.createBoard(boardData, userId, false, haveDividedBoards); let teamData; @@ -155,7 +155,12 @@ export default class CreateBoardServiceImpl implements CreateBoardService { } if (!haveDividedBoards && !team) { - newUsers = [...users]; + users.forEach((user) => + newUsers.push({ + ...user, + votesCount: 0 + }) + ); } await this.saveBoardUsers(newUsers, newBoard._id); diff --git a/backend/src/modules/boards/services/update.board.service.ts b/backend/src/modules/boards/services/update.board.service.ts index 25289bc84..7629375b7 100644 --- a/backend/src/modules/boards/services/update.board.service.ts +++ b/backend/src/modules/boards/services/update.board.service.ts @@ -15,6 +15,7 @@ import { CommunicationServiceInterface } from 'src/modules/communication/interfa import * as CommunicationsType from 'src/modules/communication/interfaces/types'; import { GetTeamServiceInterface } from 'src/modules/teams/interfaces/services/get.team.service.interface'; import * as Teams from 'src/modules/teams/interfaces/types'; +import * as Votes from 'src/modules/votes/interfaces/types'; import User, { UserDocument } from 'src/modules/users/entities/user.schema'; import { UpdateBoardDto } from '../dto/update-board.dto'; import { ResponsibleType } from '../interfaces/responsible.interface'; @@ -25,6 +26,9 @@ import { BoardDataPopulate } from '../utils/populate-board'; import { UpdateColumnDto } from '../dto/column/update-column.dto'; import { UPDATE_FAILED } from 'src/libs/exceptions/messages'; import SocketGateway from 'src/modules/socket/gateway/socket.gateway'; +import { DeleteVoteServiceInterface } from 'src/modules/votes/interfaces/services/delete.vote.service.interface'; +import Column from '../schemas/column.schema'; +import ColumnDto from '../dto/column/column.dto'; @Injectable() export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterface { @@ -36,7 +40,9 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa private slackCommunicationService: CommunicationServiceInterface, @InjectModel(BoardUser.name) private boardUserModel: Model, - private socketService: SocketGateway + private socketService: SocketGateway, + @Inject(Votes.TYPES.services.DeleteVoteService) + private deleteVoteService: DeleteVoteServiceInterface ) {} /** @@ -164,6 +170,64 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa board.addCards = boardData.addCards; board.hideVotes = boardData.hideVotes; + /** + * Validate if: + * - have columns to delete + * Returns the votes to the user + */ + if (boardData.deletedColumns && !isEmpty(boardData.deletedColumns)) { + const cardsToDelete = boardData.deletedColumns.flatMap((deletedColumnId: string) => { + return board.columns.find((column) => column._id.toString() === deletedColumnId)?.cards; + }); + + cardsToDelete.forEach((cards) => { + cards.items.forEach(async (card) => { + const votesByUser = new Map(); + + card.votes.forEach((userId) => { + if (!votesByUser.has(userId.toString())) { + votesByUser.set(userId.toString(), 1); + } else { + const count = votesByUser.get(userId.toString()); + + votesByUser.set(userId.toString(), count + 1); + } + }); + + votesByUser.forEach(async (votesCount, userId) => { + await this.deleteVoteService.decrementVoteUser(board.id, userId, -votesCount); + }); + }); + }); + } + + /** + * Only the regular boards will have their columns updated + * + * */ + + if (!isSubBoard && isEmpty(boardData.dividedBoards)) { + board.columns = boardData.columns.flatMap((col: Column | ColumnDto) => { + if (col._id) { + const columnBoard = board.columns.find((colBoard) => colBoard._id === col._id.toString()); + + if (columnBoard) { + return [{ ...columnBoard, title: col.title }]; + } + + const columnToDelete = boardData.deletedColumns.some( + (colId) => colId === col._id.toString() + ); + + if (columnToDelete) { + return []; + } + } + + return [{ ...col }]; + }) as Column[]; + } + /** * Only can change the maxVotes if: * - new maxVotes not empty @@ -197,6 +261,12 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa .lean() .exec(); + if (!updatedBoard) throw new BadRequestException(UPDATE_FAILED); + + if (boardData.socketId) { + this.socketService.sendUpdatedBoard(boardId, boardData.socketId); + } + if ( updatedBoard && currentResponsible.id !== newResponsible.id && From 55d5e6cb78e703900ee76111d238d4e20730f334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 2 Feb 2023 13:00:59 +0000 Subject: [PATCH 2/9] feat: add endpoint to delete columns --- frontend/src/api/boardService.tsx | 2 +- .../src/components/Board/RegularBoard/index.tsx | 14 +++++++++++--- frontend/src/components/Board/Settings/index.tsx | 8 +++++++- .../Settings/partials/Columns/DeleteButton.tsx | 10 ++++++++-- frontend/src/store/board/atoms/board.atom.tsx | 5 +++++ frontend/src/types/board/useBoard.ts | 2 +- 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/frontend/src/api/boardService.tsx b/frontend/src/api/boardService.tsx index 0f42a7549..fce108998 100644 --- a/frontend/src/api/boardService.tsx +++ b/frontend/src/api/boardService.tsx @@ -22,7 +22,7 @@ export const createBoardRequest = (newBoard: CreateBoardDto): Promise fetchData(`/boards`, { method: 'POST', data: newBoard }); export const updateBoardRequest = ( - board: UpdateBoardType & { socketId: string }, + board: UpdateBoardType & { socketId: string; deletedColumns?: string[] }, ): Promise => fetchData(`/boards/${board._id}`, { method: 'PUT', data: board }); export const getBoardRequest = ( diff --git a/frontend/src/components/Board/RegularBoard/index.tsx b/frontend/src/components/Board/RegularBoard/index.tsx index cc02487f9..e2ddab6b6 100644 --- a/frontend/src/components/Board/RegularBoard/index.tsx +++ b/frontend/src/components/Board/RegularBoard/index.tsx @@ -6,7 +6,11 @@ import { Container } from '@/styles/pages/boards/board.styles'; import DragDropArea from '@/components/Board/DragDropArea'; import LoadingPage from '@/components/loadings/LoadingPage'; import Flex from '@/components/Primitives/Flex'; -import { boardInfoState, editColumnsState } from '@/store/board/atoms/board.atom'; +import { + boardInfoState, + deletedColumnsState, + editColumnsState, +} from '@/store/board/atoms/board.atom'; import { BoardUserRoles } from '@/utils/enums/board.user.roles'; import Button from '@/components/Primitives/Button'; import Icon from '@/components/icons/Icon'; @@ -26,10 +30,14 @@ const RegularBoard = ({ socketId }: RegularBoardProps) => { // Recoil States const { board } = useRecoilValue(boardInfoState); const setEditColumns = useSetRecoilState(editColumnsState); + const setDeletedColumns = useSetRecoilState(deletedColumnsState); useMemo(() => { - if (!isOpen) setEditColumns(board.columns); - }, [board.columns, isOpen, setEditColumns]); + if (!isOpen) { + setEditColumns(board.columns); + setDeletedColumns([]); + } + }, [board.columns, isOpen, setDeletedColumns, setEditColumns]); // Session Details const { data: session } = useSession({ required: true }); diff --git a/frontend/src/components/Board/Settings/index.tsx b/frontend/src/components/Board/Settings/index.tsx index a7dd73b4d..4f9f1dbb6 100644 --- a/frontend/src/components/Board/Settings/index.tsx +++ b/frontend/src/components/Board/Settings/index.tsx @@ -13,7 +13,11 @@ import Separator from '@/components/Primitives/Separator'; import Text from '@/components/Primitives/Text'; import useBoard from '@/hooks/useBoard'; import SchemaUpdateBoard from '@/schema/schemaUpdateBoardForm'; -import { boardInfoState, editColumnsState } from '@/store/board/atoms/board.atom'; +import { + boardInfoState, + deletedColumnsState, + editColumnsState, +} from '@/store/board/atoms/board.atom'; import { UpdateBoardType } from '@/types/board/board'; import { BoardUserToAdd } from '@/types/board/board.user'; import { BoardUserRoles } from '@/utils/enums/board.user.roles'; @@ -73,6 +77,7 @@ const BoardSettings = ({ } = useRecoilValue(boardInfoState); const [editColumns, setEditColumns] = useRecoilState(editColumnsState); + const deletedColumns = useRecoilValue(deletedColumnsState); // State used to change values const initialData: UpdateBoardType = { @@ -265,6 +270,7 @@ const BoardSettings = ({ title, maxVotes, columns: isRegularBoard ? updatedColumns : data.columns, + deletedColumns, socketId, responsible: data.users?.find((user) => user.role === BoardUserRoles.RESPONSIBLE), }, diff --git a/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx b/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx index 581e03030..646927782 100644 --- a/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx +++ b/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx @@ -3,7 +3,7 @@ import Text from '@/components/Primitives/Text'; // import { AlertDialogTrigger } from '@radix-ui/react-alert-dialog'; import Tooltip from '@/components/Primitives/Tooltip'; import Icon from '@/components/icons/Icon'; -import { editColumnsState } from '@/store/board/atoms/board.atom'; +import { deletedColumnsState, editColumnsState } from '@/store/board/atoms/board.atom'; import { useRecoilState } from 'recoil'; import { AlertDialog, @@ -13,6 +13,7 @@ import { AlertDialogTrigger, } from '@/components/Primitives/AlertDialog'; import Button from '@/components/Primitives/Button'; +import ColumnType from '@/types/column'; interface Props { columnTitle: string; @@ -22,10 +23,15 @@ interface Props { const DeleteColumnButton = ({ columnTitle, columnIndex, disableDeleteColumn }: Props) => { const [editColumns, setEditColumns] = useRecoilState(editColumnsState); + const [deletedColumns, setDeletedColumns] = useRecoilState(deletedColumnsState); + const handleDeleteColumn = () => { const arrayWithoutColumn = [...editColumns]; - arrayWithoutColumn.splice(columnIndex, 1); + + const column = arrayWithoutColumn.splice(columnIndex, 1)[0] as ColumnType; + setEditColumns(arrayWithoutColumn); + if (column._id) setDeletedColumns([...deletedColumns, column._id]); }; return ( diff --git a/frontend/src/store/board/atoms/board.atom.tsx b/frontend/src/store/board/atoms/board.atom.tsx index 202d86b66..0d9ac457d 100644 --- a/frontend/src/store/board/atoms/board.atom.tsx +++ b/frontend/src/store/board/atoms/board.atom.tsx @@ -27,3 +27,8 @@ export const editColumnsState = atom<(ColumnType | CreateColumn)[]>({ key: 'editColumns', default: [], }); + +export const deletedColumnsState = atom({ + key: 'deletedColumns', + default: [], +}); diff --git a/frontend/src/types/board/useBoard.ts b/frontend/src/types/board/useBoard.ts index 54f076141..883faf5fc 100644 --- a/frontend/src/types/board/useBoard.ts +++ b/frontend/src/types/board/useBoard.ts @@ -7,7 +7,7 @@ export default interface UseBoardType { updateBoard: UseMutationResult< BoardType, unknown, - UpdateBoardType & { socketId: string }, + UpdateBoardType & { socketId: string; deletedColumns?: string[] }, unknown >; deleteBoard: UseMutationResult< From e8a3ae3369a2e7afa58b0584ea7f8f13e3397b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 2 Feb 2023 14:49:34 +0000 Subject: [PATCH 3/9] fix: handle votes --- frontend/src/helper/board/transformBoard.tsx | 3 ++- frontend/src/pages/boards/[boardId].tsx | 15 ++++++++++++--- frontend/src/pages/boards/newRegularBoard.tsx | 6 +++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/frontend/src/helper/board/transformBoard.tsx b/frontend/src/helper/board/transformBoard.tsx index 225e72480..392cb1bc3 100644 --- a/frontend/src/helper/board/transformBoard.tsx +++ b/frontend/src/helper/board/transformBoard.tsx @@ -113,7 +113,8 @@ export const handleDeleteCard = (board: BoardType, data: DeleteCardDto): BoardTy } const boardUserIdx = boardData.users.findIndex((bUser) => bUser.user._id === userId); - if (boardUserIdx) { + + if (boardUserIdx > -1) { boardData.users[boardUserIdx].votesCount -= votesOfUser; } diff --git a/frontend/src/pages/boards/[boardId].tsx b/frontend/src/pages/boards/[boardId].tsx index 676c5261c..de116d4e2 100644 --- a/frontend/src/pages/boards/[boardId].tsx +++ b/frontend/src/pages/boards/[boardId].tsx @@ -3,7 +3,7 @@ import { dehydrate, QueryClient } from '@tanstack/react-query'; import { GetServerSideProps, NextPage } from 'next'; import { useRouter } from 'next/router'; import { getSession, useSession } from 'next-auth/react'; -import { useRecoilState } from 'recoil'; +import { useRecoilState, useSetRecoilState } from 'recoil'; import { Container } from '@/styles/pages/boards/board.styles'; @@ -15,7 +15,12 @@ import AlertBox from '@/components/Primitives/AlertBox'; import Flex from '@/components/Primitives/Flex'; import useBoard from '@/hooks/useBoard'; import { useSocketIO } from '@/hooks/useSocketIO'; -import { boardInfoState, newBoardState } from '@/store/board/atoms/board.atom'; +import { + boardInfoState, + deletedColumnsState, + editColumnsState, + newBoardState, +} from '@/store/board/atoms/board.atom'; import { BoardUserRoles } from '@/utils/enums/board.user.roles'; import { TeamUserRoles } from '@/utils/enums/team.user.roles'; import isEmpty from '@/utils/isEmpty'; @@ -94,6 +99,8 @@ const Board: NextPage = ({ boardId, mainBoardId }) => { // Recoil States const [newBoard, setNewBoard] = useRecoilState(newBoardState); const [recoilBoard, setRecoilBoard] = useRecoilState(boardInfoState); + const setEditColumns = useSetRecoilState(editColumnsState); + const setDeletedColumns = useSetRecoilState(deletedColumnsState); // Session Details const { data: session } = useSession(); @@ -124,8 +131,10 @@ const Board: NextPage = ({ boardId, mainBoardId }) => { useEffect(() => { if (data) { setRecoilBoard(data); + setEditColumns(data.board.columns); + setDeletedColumns([]); } - }, [data, setRecoilBoard]); + }, [data, setDeletedColumns, setEditColumns, setRecoilBoard]); // Board Settings permissions const isStakeholderOrAdmin = useMemo( diff --git a/frontend/src/pages/boards/newRegularBoard.tsx b/frontend/src/pages/boards/newRegularBoard.tsx index 10ea79a19..4d52d6934 100644 --- a/frontend/src/pages/boards/newRegularBoard.tsx +++ b/frontend/src/pages/boards/newRegularBoard.tsx @@ -122,7 +122,7 @@ const NewRegularBoard: NextPage = () => { reValidateMode: 'onBlur', defaultValues: { text: '', - maxVotes: 2, + maxVotes: boardState.board.maxVotes, slackEnable: false, }, resolver: joiResolver(SchemaCreateRegularBoard), @@ -181,7 +181,7 @@ const NewRegularBoard: NextPage = () => { mutate({ ...boardState.board, users: isEmpty(boardState.users) ? users : boardState.users, - title: title || boardState.board.title, + title: title || defaultBoard.board.title, dividedBoards: [], maxVotes, slackEnable, @@ -200,7 +200,7 @@ const NewRegularBoard: NextPage = () => { mutate({ ...boardState.board, users: isEmpty(boardState.users) ? users : boardState.users, - title: boardState.board.title, + title: defaultBoard.board.title, dividedBoards: [], maxUsers: boardState.count.maxUsersCount, recurrent: false, From 1884e1196318b5194cdf755a6db930c70a8a676a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 2 Feb 2023 16:09:24 +0000 Subject: [PATCH 4/9] fix: cast responsible id to string --- backend/src/modules/boards/services/update.board.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/modules/boards/services/update.board.service.ts b/backend/src/modules/boards/services/update.board.service.ts index f5b3ae6ec..c9b737ca9 100644 --- a/backend/src/modules/boards/services/update.board.service.ts +++ b/backend/src/modules/boards/services/update.board.service.ts @@ -104,7 +104,7 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa * - is a sub-board * - and the logged user isn't the current responsible */ - if (boardData.users && currentResponsible.id !== newResponsible.id) { + if (boardData.users && String(currentResponsible.id) !== String(newResponsible.id)) { if (isSubBoard) { const promises = boardData.users .filter((boardUser) => From 280c5f3650064bb4aafc097b64ebf0cbf0008e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 2 Feb 2023 16:16:07 +0000 Subject: [PATCH 5/9] fix: check board for divided boards --- backend/src/modules/boards/services/update.board.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/modules/boards/services/update.board.service.ts b/backend/src/modules/boards/services/update.board.service.ts index c9b737ca9..123edfc8f 100644 --- a/backend/src/modules/boards/services/update.board.service.ts +++ b/backend/src/modules/boards/services/update.board.service.ts @@ -206,7 +206,7 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa * * */ - if (!isSubBoard && isEmpty(boardData.dividedBoards)) { + if (!isSubBoard && isEmpty(board.dividedBoards)) { board.columns = boardData.columns.flatMap((col: Column | ColumnDto) => { if (col._id) { const columnBoard = board.columns.find((colBoard) => colBoard._id === col._id.toString()); From 609ec5170a5b971938e16cd7b81df88ee1ea2d49 Mon Sep 17 00:00:00 2001 From: Nuno Caseiro <90208434+nunocaseiro@users.noreply.github.com> Date: Thu, 2 Feb 2023 16:24:29 +0000 Subject: [PATCH 6/9] fix: new responsible validation (#1001) --- backend/src/modules/boards/services/update.board.service.ts | 4 ++-- .../applications/slack-communication.application.ts | 4 ++-- .../applications/slack-merge-board.application.ts | 2 +- .../applications/slack-responsible.application.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/modules/boards/services/update.board.service.ts b/backend/src/modules/boards/services/update.board.service.ts index 5919b60e4..f052131f8 100644 --- a/backend/src/modules/boards/services/update.board.service.ts +++ b/backend/src/modules/boards/services/update.board.service.ts @@ -98,11 +98,11 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa * - is a sub-board * - and the logged user isn't the current responsible */ - if (boardData.users && currentResponsible.id !== newResponsible.id) { + if (boardData.users && String(currentResponsible.id) !== String(newResponsible.id)) { if (isSubBoard) { const promises = boardData.users .filter((boardUser) => - [getIdFromObjectId(String(currentResponsible?.id)), newResponsible.id].includes( + [getIdFromObjectId(String(currentResponsible?.id)), String(newResponsible.id)].includes( (boardUser.user as unknown as User)._id ) ) diff --git a/backend/src/modules/communication/applications/slack-communication.application.ts b/backend/src/modules/communication/applications/slack-communication.application.ts index 3e1f83141..8734ada80 100644 --- a/backend/src/modules/communication/applications/slack-communication.application.ts +++ b/backend/src/modules/communication/applications/slack-communication.application.ts @@ -71,12 +71,12 @@ export class SlackCommunicationApplication implements CommunicationApplicationIn const generalText = { member: ( boardId: string - ) => ` In order to proceed with the retro of this month, here is the board link: \n\n + ) => ` In order to proceed with the retro of this month, here is the board link: \n\n ${this.config.frontendUrl}/boards/${boardId} `, responsible: ( boardId: string - ) => ` In order to proceed with the retro of this month, here is the main board link: \n\n + ) => ` In order to proceed with the retro of this month, here is the main board link: \n\n ${this.config.frontendUrl}/boards/${boardId} ` }; diff --git a/backend/src/modules/communication/applications/slack-merge-board.application.ts b/backend/src/modules/communication/applications/slack-merge-board.application.ts index 29ab998f1..8e33dfee8 100644 --- a/backend/src/modules/communication/applications/slack-merge-board.application.ts +++ b/backend/src/modules/communication/applications/slack-merge-board.application.ts @@ -10,7 +10,7 @@ export class SlackMergeBoardApplication implements MergeBoardApplicationInterfac async execute(data: MergeBoardType): Promise { const { responsiblesChannelId, teamNumber, isLastSubBoard } = data; - const message = `, The board of team ${teamNumber} is ready`; + const message = `, The board of team ${teamNumber} is ready`; this.chatHandler.postMessage(responsiblesChannelId, message); if (isLastSubBoard) { diff --git a/backend/src/modules/communication/applications/slack-responsible.application.ts b/backend/src/modules/communication/applications/slack-responsible.application.ts index 57e7d62c9..3a6059992 100644 --- a/backend/src/modules/communication/applications/slack-responsible.application.ts +++ b/backend/src/modules/communication/applications/slack-responsible.application.ts @@ -22,7 +22,7 @@ export class SlackResponsibleApplication implements ResponsibleApplicationInterf const newResponsibleId = await this.usersHandler.getSlackUserIdByEmail(newResponsibleEmail); - const message = `, <@${newResponsibleId}> is the new responsible for the team ${teamNumber}`; + const message = `, <@${newResponsibleId}> is the new responsible for the team ${teamNumber}`; if (mainChannelId) { await this.chatHandler.postMessage(mainChannelId, message); From 8849efc463bdb7044a074aaca8ab9ca748984cd0 Mon Sep 17 00:00:00 2001 From: rpvsilva Date: Thu, 2 Feb 2023 16:31:19 +0000 Subject: [PATCH 7/9] ci: update version to v0.1.10 [skip ci] --- CHANGELOG.md | 17 ++++++++++++++++- backend/package.json | 2 +- frontend/package.json | 2 +- package.json | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2057658f..b77c741b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,22 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/xgeekshq/split/compare/v0.1.9...HEAD) +## [Unreleased](https://github.com/xgeekshq/split/compare/v0.1.10...HEAD) + +## [v0.1.10](https://github.com/xgeekshq/split/compare/v0.1.9...v0.1.10) - 2023-02-02 + +### What Changed 👀 + +### 🐛 Bug Fixes + +- fix: new responsible validation @nunocaseiro (#1001) +- fix: isNewJoiner period and votes @CatiaAntunes96 (#1000) + +### 📄 Documentation + +- feat: popover primitive refactor and story @JoaoSaIvador (#993) + +**Full Changelog**: https://github.com/xgeekshq/split/compare/v0.1.9...v0.1.10 ## [v0.1.9](https://github.com/xgeekshq/split/compare/v0.1.8...v0.1.9) - 2023-02-02 diff --git a/backend/package.json b/backend/package.json index 30f9a7819..1c5acb1ba 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "backend", - "version": "v0.1.9", + "version": "v0.1.10", "description": "", "author": "", "private": true, diff --git a/frontend/package.json b/frontend/package.json index e98479efa..3030b2518 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "v0.1.9", + "version": "v0.1.10", "private": true, "scripts": { "dev": "next dev", diff --git a/package.json b/package.json index 33cc91d08..fc4d95afb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "split", - "version": "v0.1.9", + "version": "v0.1.10", "private": true, "scripts": { "prepare": "concurrently \"npm:prepare:backend\" \"npm:prepare:frontend\" \"husky install\"", From c0786d3e06082bd23062d78490831ed37c361042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 2 Feb 2023 17:42:25 +0000 Subject: [PATCH 8/9] feat: delete board columns/handle votes (#994) --- backend/src/modules/boards/boards.module.ts | 2 + .../controller/boards.controller.spec.ts | 4 ++ .../boards/controller/boards.controller.ts | 12 +--- .../modules/boards/dto/update-board.dto.ts | 8 ++- .../boards/services/create.board.service.ts | 9 ++- .../boards/services/update.board.service.ts | 72 ++++++++++++++++++- frontend/src/api/boardService.tsx | 2 +- .../components/Board/RegularBoard/index.tsx | 14 +++- .../src/components/Board/Settings/index.tsx | 8 ++- .../partials/Columns/DeleteButton.tsx | 10 ++- frontend/src/store/board/atoms/board.atom.tsx | 5 ++ frontend/src/types/board/useBoard.ts | 2 +- 12 files changed, 126 insertions(+), 22 deletions(-) diff --git a/backend/src/modules/boards/boards.module.ts b/backend/src/modules/boards/boards.module.ts index f400be662..40e24cd14 100644 --- a/backend/src/modules/boards/boards.module.ts +++ b/backend/src/modules/boards/boards.module.ts @@ -7,6 +7,7 @@ import { CommunicationModule } from 'src/modules/communication/communication.mod import { SchedulesModule } from 'src/modules/schedules/schedules.module'; import TeamsModule from 'src/modules/teams/teams.module'; import UsersModule from 'src/modules/users/users.module'; +import { VotesModule } from '../votes/votes.module'; import { createBoardApplication, createBoardService, @@ -23,6 +24,7 @@ import BoardsController from './controller/boards.controller'; imports: [ UsersModule, forwardRef(() => TeamsModule), + VotesModule, SchedulesModule, CommunicationModule, mongooseBoardModule, diff --git a/backend/src/modules/boards/controller/boards.controller.spec.ts b/backend/src/modules/boards/controller/boards.controller.spec.ts index 168c69a9d..7f1930974 100644 --- a/backend/src/modules/boards/controller/boards.controller.spec.ts +++ b/backend/src/modules/boards/controller/boards.controller.spec.ts @@ -12,6 +12,7 @@ import { updateBoardService } from 'src/modules/boards/boards.providers'; import BoardsController from 'src/modules/boards/controller/boards.controller'; +import { getCardService } from 'src/modules/cards/cards.providers'; import * as CommunicationsType from 'src/modules/communication/interfaces/types'; import { createSchedulesService, @@ -26,6 +27,7 @@ import { teamUserRepository, updateTeamService } from 'src/modules/teams/providers'; +import { deleteVoteService } from 'src/modules/votes/votes.providers'; describe('BoardsController', () => { let controller: BoardsController; @@ -52,6 +54,8 @@ describe('BoardsController', () => { teamRepository, teamUserRepository, updateTeamService, + deleteVoteService, + getCardService, { provide: getModelToken('User'), useValue: {} diff --git a/backend/src/modules/boards/controller/boards.controller.ts b/backend/src/modules/boards/controller/boards.controller.ts index 8745d54cb..d726506d9 100644 --- a/backend/src/modules/boards/controller/boards.controller.ts +++ b/backend/src/modules/boards/controller/boards.controller.ts @@ -235,16 +235,8 @@ export default class BoardsController { @BoardUser([BoardRoles.RESPONSIBLE, TeamRoles.ADMIN, TeamRoles.STAKEHOLDER]) @UseGuards(BoardUserGuard) @Put(':boardId') - async updateBoard(@Param() { boardId }: BaseParam, @Body() boardData: UpdateBoardDto) { - const board = await this.updateBoardApp.update(boardId, boardData); - - if (!board) throw new BadRequestException(UPDATE_FAILED); - - if (boardData.socketId) { - this.socketService.sendUpdatedBoard(boardId, boardData.socketId); - } - - return board; + updateBoard(@Param() { boardId }: BaseParam, @Body() boardData: UpdateBoardDto) { + return this.updateBoardApp.update(boardId, boardData); } @ApiOperation({ summary: 'Delete a specific board' }) diff --git a/backend/src/modules/boards/dto/update-board.dto.ts b/backend/src/modules/boards/dto/update-board.dto.ts index b955ff3cb..03cc85cca 100644 --- a/backend/src/modules/boards/dto/update-board.dto.ts +++ b/backend/src/modules/boards/dto/update-board.dto.ts @@ -1,5 +1,6 @@ import { PartialType } from '@nestjs/mapped-types'; -import { ApiPropertyOptional } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; import { IsOptional } from 'class-validator'; import BoardUser from '../schemas/board.user.schema'; import BoardDto from './board.dto'; @@ -8,4 +9,9 @@ export class UpdateBoardDto extends PartialType(BoardDto) { @ApiPropertyOptional({ type: BoardUser, isArray: true }) @IsOptional() responsible?: BoardUser; + + @ApiProperty({ type: String, isArray: true }) + @IsOptional() + @Type(() => String) + deletedColumns?: string[]; } diff --git a/backend/src/modules/boards/services/create.board.service.ts b/backend/src/modules/boards/services/create.board.service.ts index 0d186095c..6faf5da8f 100644 --- a/backend/src/modules/boards/services/create.board.service.ts +++ b/backend/src/modules/boards/services/create.board.service.ts @@ -144,7 +144,7 @@ export default class CreateBoardServiceImpl implements CreateBoardService { const { team, recurrent, maxUsers, slackEnable, users, dividedBoards } = boardData; const haveDividedBoards = dividedBoards.length > 0 ? true : false; - let newUsers = []; + const newUsers = []; const newBoard = await this.createBoard(boardData, userId, false, haveDividedBoards); let teamData; @@ -155,7 +155,12 @@ export default class CreateBoardServiceImpl implements CreateBoardService { } if (!haveDividedBoards && !team) { - newUsers = [...users]; + users.forEach((user) => + newUsers.push({ + ...user, + votesCount: 0 + }) + ); } await this.saveBoardUsers(newUsers, newBoard._id); diff --git a/backend/src/modules/boards/services/update.board.service.ts b/backend/src/modules/boards/services/update.board.service.ts index f052131f8..0fbdad1d3 100644 --- a/backend/src/modules/boards/services/update.board.service.ts +++ b/backend/src/modules/boards/services/update.board.service.ts @@ -15,6 +15,7 @@ import { CommunicationServiceInterface } from 'src/modules/communication/interfa import * as CommunicationsType from 'src/modules/communication/interfaces/types'; import { GetTeamServiceInterface } from 'src/modules/teams/interfaces/services/get.team.service.interface'; import * as Teams from 'src/modules/teams/interfaces/types'; +import * as Votes from 'src/modules/votes/interfaces/types'; import User, { UserDocument } from 'src/modules/users/entities/user.schema'; import { UpdateBoardDto } from '../dto/update-board.dto'; import { ResponsibleType } from '../interfaces/responsible.interface'; @@ -25,6 +26,9 @@ import { BoardDataPopulate } from '../utils/populate-board'; import { UpdateColumnDto } from '../dto/column/update-column.dto'; import { UPDATE_FAILED } from 'src/libs/exceptions/messages'; import SocketGateway from 'src/modules/socket/gateway/socket.gateway'; +import { DeleteVoteServiceInterface } from 'src/modules/votes/interfaces/services/delete.vote.service.interface'; +import Column from '../schemas/column.schema'; +import ColumnDto from '../dto/column/column.dto'; @Injectable() export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterface { @@ -36,7 +40,9 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa private slackCommunicationService: CommunicationServiceInterface, @InjectModel(BoardUser.name) private boardUserModel: Model, - private socketService: SocketGateway + private socketService: SocketGateway, + @Inject(Votes.TYPES.services.DeleteVoteService) + private deleteVoteService: DeleteVoteServiceInterface ) {} /** @@ -164,6 +170,64 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa board.addCards = boardData.addCards; board.hideVotes = boardData.hideVotes; + /** + * Validate if: + * - have columns to delete + * Returns the votes to the user + */ + if (boardData.deletedColumns && !isEmpty(boardData.deletedColumns)) { + const cardsToDelete = boardData.deletedColumns.flatMap((deletedColumnId: string) => { + return board.columns.find((column) => column._id.toString() === deletedColumnId)?.cards; + }); + + cardsToDelete.forEach((cards) => { + cards.items.forEach(async (card) => { + const votesByUser = new Map(); + + card.votes.forEach((userId) => { + if (!votesByUser.has(userId.toString())) { + votesByUser.set(userId.toString(), 1); + } else { + const count = votesByUser.get(userId.toString()); + + votesByUser.set(userId.toString(), count + 1); + } + }); + + votesByUser.forEach(async (votesCount, userId) => { + await this.deleteVoteService.decrementVoteUser(board.id, userId, -votesCount); + }); + }); + }); + } + + /** + * Only the regular boards will have their columns updated + * + * */ + + if (!isSubBoard && isEmpty(board.dividedBoards)) { + board.columns = boardData.columns.flatMap((col: Column | ColumnDto) => { + if (col._id) { + const columnBoard = board.columns.find((colBoard) => colBoard._id === col._id.toString()); + + if (columnBoard) { + return [{ ...columnBoard, title: col.title }]; + } + + const columnToDelete = boardData.deletedColumns.some( + (colId) => colId === col._id.toString() + ); + + if (columnToDelete) { + return []; + } + } + + return [{ ...col }]; + }) as Column[]; + } + /** * Only can change the maxVotes if: * - new maxVotes not empty @@ -197,6 +261,12 @@ export default class UpdateBoardServiceImpl implements UpdateBoardServiceInterfa .lean() .exec(); + if (!updatedBoard) throw new BadRequestException(UPDATE_FAILED); + + if (boardData.socketId) { + this.socketService.sendUpdatedBoard(boardId, boardData.socketId); + } + if ( updatedBoard && newResponsible && diff --git a/frontend/src/api/boardService.tsx b/frontend/src/api/boardService.tsx index 0f42a7549..fce108998 100644 --- a/frontend/src/api/boardService.tsx +++ b/frontend/src/api/boardService.tsx @@ -22,7 +22,7 @@ export const createBoardRequest = (newBoard: CreateBoardDto): Promise fetchData(`/boards`, { method: 'POST', data: newBoard }); export const updateBoardRequest = ( - board: UpdateBoardType & { socketId: string }, + board: UpdateBoardType & { socketId: string; deletedColumns?: string[] }, ): Promise => fetchData(`/boards/${board._id}`, { method: 'PUT', data: board }); export const getBoardRequest = ( diff --git a/frontend/src/components/Board/RegularBoard/index.tsx b/frontend/src/components/Board/RegularBoard/index.tsx index cc02487f9..e2ddab6b6 100644 --- a/frontend/src/components/Board/RegularBoard/index.tsx +++ b/frontend/src/components/Board/RegularBoard/index.tsx @@ -6,7 +6,11 @@ import { Container } from '@/styles/pages/boards/board.styles'; import DragDropArea from '@/components/Board/DragDropArea'; import LoadingPage from '@/components/loadings/LoadingPage'; import Flex from '@/components/Primitives/Flex'; -import { boardInfoState, editColumnsState } from '@/store/board/atoms/board.atom'; +import { + boardInfoState, + deletedColumnsState, + editColumnsState, +} from '@/store/board/atoms/board.atom'; import { BoardUserRoles } from '@/utils/enums/board.user.roles'; import Button from '@/components/Primitives/Button'; import Icon from '@/components/icons/Icon'; @@ -26,10 +30,14 @@ const RegularBoard = ({ socketId }: RegularBoardProps) => { // Recoil States const { board } = useRecoilValue(boardInfoState); const setEditColumns = useSetRecoilState(editColumnsState); + const setDeletedColumns = useSetRecoilState(deletedColumnsState); useMemo(() => { - if (!isOpen) setEditColumns(board.columns); - }, [board.columns, isOpen, setEditColumns]); + if (!isOpen) { + setEditColumns(board.columns); + setDeletedColumns([]); + } + }, [board.columns, isOpen, setDeletedColumns, setEditColumns]); // Session Details const { data: session } = useSession({ required: true }); diff --git a/frontend/src/components/Board/Settings/index.tsx b/frontend/src/components/Board/Settings/index.tsx index a7dd73b4d..4f9f1dbb6 100644 --- a/frontend/src/components/Board/Settings/index.tsx +++ b/frontend/src/components/Board/Settings/index.tsx @@ -13,7 +13,11 @@ import Separator from '@/components/Primitives/Separator'; import Text from '@/components/Primitives/Text'; import useBoard from '@/hooks/useBoard'; import SchemaUpdateBoard from '@/schema/schemaUpdateBoardForm'; -import { boardInfoState, editColumnsState } from '@/store/board/atoms/board.atom'; +import { + boardInfoState, + deletedColumnsState, + editColumnsState, +} from '@/store/board/atoms/board.atom'; import { UpdateBoardType } from '@/types/board/board'; import { BoardUserToAdd } from '@/types/board/board.user'; import { BoardUserRoles } from '@/utils/enums/board.user.roles'; @@ -73,6 +77,7 @@ const BoardSettings = ({ } = useRecoilValue(boardInfoState); const [editColumns, setEditColumns] = useRecoilState(editColumnsState); + const deletedColumns = useRecoilValue(deletedColumnsState); // State used to change values const initialData: UpdateBoardType = { @@ -265,6 +270,7 @@ const BoardSettings = ({ title, maxVotes, columns: isRegularBoard ? updatedColumns : data.columns, + deletedColumns, socketId, responsible: data.users?.find((user) => user.role === BoardUserRoles.RESPONSIBLE), }, diff --git a/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx b/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx index 581e03030..646927782 100644 --- a/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx +++ b/frontend/src/components/Board/Settings/partials/Columns/DeleteButton.tsx @@ -3,7 +3,7 @@ import Text from '@/components/Primitives/Text'; // import { AlertDialogTrigger } from '@radix-ui/react-alert-dialog'; import Tooltip from '@/components/Primitives/Tooltip'; import Icon from '@/components/icons/Icon'; -import { editColumnsState } from '@/store/board/atoms/board.atom'; +import { deletedColumnsState, editColumnsState } from '@/store/board/atoms/board.atom'; import { useRecoilState } from 'recoil'; import { AlertDialog, @@ -13,6 +13,7 @@ import { AlertDialogTrigger, } from '@/components/Primitives/AlertDialog'; import Button from '@/components/Primitives/Button'; +import ColumnType from '@/types/column'; interface Props { columnTitle: string; @@ -22,10 +23,15 @@ interface Props { const DeleteColumnButton = ({ columnTitle, columnIndex, disableDeleteColumn }: Props) => { const [editColumns, setEditColumns] = useRecoilState(editColumnsState); + const [deletedColumns, setDeletedColumns] = useRecoilState(deletedColumnsState); + const handleDeleteColumn = () => { const arrayWithoutColumn = [...editColumns]; - arrayWithoutColumn.splice(columnIndex, 1); + + const column = arrayWithoutColumn.splice(columnIndex, 1)[0] as ColumnType; + setEditColumns(arrayWithoutColumn); + if (column._id) setDeletedColumns([...deletedColumns, column._id]); }; return ( diff --git a/frontend/src/store/board/atoms/board.atom.tsx b/frontend/src/store/board/atoms/board.atom.tsx index 202d86b66..0d9ac457d 100644 --- a/frontend/src/store/board/atoms/board.atom.tsx +++ b/frontend/src/store/board/atoms/board.atom.tsx @@ -27,3 +27,8 @@ export const editColumnsState = atom<(ColumnType | CreateColumn)[]>({ key: 'editColumns', default: [], }); + +export const deletedColumnsState = atom({ + key: 'deletedColumns', + default: [], +}); diff --git a/frontend/src/types/board/useBoard.ts b/frontend/src/types/board/useBoard.ts index 54f076141..883faf5fc 100644 --- a/frontend/src/types/board/useBoard.ts +++ b/frontend/src/types/board/useBoard.ts @@ -7,7 +7,7 @@ export default interface UseBoardType { updateBoard: UseMutationResult< BoardType, unknown, - UpdateBoardType & { socketId: string }, + UpdateBoardType & { socketId: string; deletedColumns?: string[] }, unknown >; deleteBoard: UseMutationResult< From 2b7141b341b4994c8a03054e3358651021f55156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1tia=20Antunes?= Date: Thu, 2 Feb 2023 14:49:34 +0000 Subject: [PATCH 9/9] fix: handle votes --- frontend/src/pages/boards/[boardId].tsx | 15 ++++++++++++--- frontend/src/pages/boards/newRegularBoard.tsx | 6 +++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/boards/[boardId].tsx b/frontend/src/pages/boards/[boardId].tsx index 676c5261c..de116d4e2 100644 --- a/frontend/src/pages/boards/[boardId].tsx +++ b/frontend/src/pages/boards/[boardId].tsx @@ -3,7 +3,7 @@ import { dehydrate, QueryClient } from '@tanstack/react-query'; import { GetServerSideProps, NextPage } from 'next'; import { useRouter } from 'next/router'; import { getSession, useSession } from 'next-auth/react'; -import { useRecoilState } from 'recoil'; +import { useRecoilState, useSetRecoilState } from 'recoil'; import { Container } from '@/styles/pages/boards/board.styles'; @@ -15,7 +15,12 @@ import AlertBox from '@/components/Primitives/AlertBox'; import Flex from '@/components/Primitives/Flex'; import useBoard from '@/hooks/useBoard'; import { useSocketIO } from '@/hooks/useSocketIO'; -import { boardInfoState, newBoardState } from '@/store/board/atoms/board.atom'; +import { + boardInfoState, + deletedColumnsState, + editColumnsState, + newBoardState, +} from '@/store/board/atoms/board.atom'; import { BoardUserRoles } from '@/utils/enums/board.user.roles'; import { TeamUserRoles } from '@/utils/enums/team.user.roles'; import isEmpty from '@/utils/isEmpty'; @@ -94,6 +99,8 @@ const Board: NextPage = ({ boardId, mainBoardId }) => { // Recoil States const [newBoard, setNewBoard] = useRecoilState(newBoardState); const [recoilBoard, setRecoilBoard] = useRecoilState(boardInfoState); + const setEditColumns = useSetRecoilState(editColumnsState); + const setDeletedColumns = useSetRecoilState(deletedColumnsState); // Session Details const { data: session } = useSession(); @@ -124,8 +131,10 @@ const Board: NextPage = ({ boardId, mainBoardId }) => { useEffect(() => { if (data) { setRecoilBoard(data); + setEditColumns(data.board.columns); + setDeletedColumns([]); } - }, [data, setRecoilBoard]); + }, [data, setDeletedColumns, setEditColumns, setRecoilBoard]); // Board Settings permissions const isStakeholderOrAdmin = useMemo( diff --git a/frontend/src/pages/boards/newRegularBoard.tsx b/frontend/src/pages/boards/newRegularBoard.tsx index 10ea79a19..4d52d6934 100644 --- a/frontend/src/pages/boards/newRegularBoard.tsx +++ b/frontend/src/pages/boards/newRegularBoard.tsx @@ -122,7 +122,7 @@ const NewRegularBoard: NextPage = () => { reValidateMode: 'onBlur', defaultValues: { text: '', - maxVotes: 2, + maxVotes: boardState.board.maxVotes, slackEnable: false, }, resolver: joiResolver(SchemaCreateRegularBoard), @@ -181,7 +181,7 @@ const NewRegularBoard: NextPage = () => { mutate({ ...boardState.board, users: isEmpty(boardState.users) ? users : boardState.users, - title: title || boardState.board.title, + title: title || defaultBoard.board.title, dividedBoards: [], maxVotes, slackEnable, @@ -200,7 +200,7 @@ const NewRegularBoard: NextPage = () => { mutate({ ...boardState.board, users: isEmpty(boardState.users) ? users : boardState.users, - title: boardState.board.title, + title: defaultBoard.board.title, dividedBoards: [], maxUsers: boardState.count.maxUsersCount, recurrent: false,