Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE]: Hide cards from others #302

Merged
merged 47 commits into from
Jul 17, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
bf45c81
feat(backend): hide cards from others
dsousa12 Jun 30, 2022
d285f14
feat: frontend hide cards from others
CatiaBarroco-xgeeks Jul 1, 2022
cf87e56
feat: frontend hide-cards-from-others icons
CatiaBarroco-xgeeks Jul 1, 2022
bd0864c
feat: disabel the card icons
CatiaBarroco-xgeeks Jul 1, 2022
5fce2e5
feat: disable card icon dots
CatiaBarroco-xgeeks Jul 4, 2022
7f7dd76
feat: add new util replaceChar
CatiaBarroco-xgeeks Jul 4, 2022
82b935a
feat: pr sugestions
CatiaBarroco-xgeeks Jul 6, 2022
7527dad
fix: switchs (#300)
dvpfran Jul 4, 2022
1a217bd
[FEATURE]: Remove "Option to post cards anonymously" from Board Setti…
joaosantos99 Jul 4, 2022
9017ed2
[FIX]: Disable Limit Votes (#307)
dvpfran Jul 7, 2022
7b5e3c4
fix: rebase
tutods Jul 13, 2022
704e67c
[FIX]: Remove Votes options from Board Settings on Sub-boards (#312)
joaosantos99 Jul 7, 2022
da4e8e8
chore(deps): bump next-auth from 4.6.1 to 4.9.0 in /frontend (#314)
dependabot[bot] Jul 8, 2022
2cc35cd
[FIX]: Missing upper case validation on register user (#317)
joaosantos99 Jul 8, 2022
6282fa6
docs: add geomarb as a contributor for code, doc (#322)
allcontributors[bot] Jul 12, 2022
0fc18ef
[FIX]: Extra votes left on card (#308)
joaosantos99 Jul 12, 2022
8575735
[FIX]: Edit cards from others (#320)
dvpfran Jul 12, 2022
f7d7141
[FIX]: totalUsedVotes type error (#325)
joaosantos99 Jul 12, 2022
472e49f
Fix build errors (#327)
joaosantos99 Jul 12, 2022
fd7e844
chore(deps): bump moment from 2.29.3 to 2.29.4 in /backend (#323)
dependabot[bot] Jul 12, 2022
f75e5d2
[FIX]: Deleting a card will not return votes to users (#319)
FranciscoGaspar Jul 13, 2022
b0bc66a
[FEATURE]: hide votes from others on the board (#309)
mourabraz Jul 13, 2022
63f2ff1
feat: frontend hide cards from others
CatiaBarroco-xgeeks Jul 1, 2022
89a5c25
feat: disable card icon dots
CatiaBarroco-xgeeks Jul 4, 2022
3a8af76
feat: add new util replaceChar
CatiaBarroco-xgeeks Jul 4, 2022
052f311
feat: pr sugestions
CatiaBarroco-xgeeks Jul 6, 2022
370489c
feat: improve concurrently scripts
tutods Jul 13, 2022
77f0f07
fix: title warning
tutods Jul 13, 2022
67952c3
fix: register and use socket on update board
tutods Jul 14, 2022
f4381b5
fix: register and use socket on update board
tutods Jul 14, 2022
45d1e22
fix: register and use socket on update board
tutods Jul 14, 2022
3d49354
feat: update pre-commit config
tutods Jul 14, 2022
d51c5be
feat: update pre-commit config
tutods Jul 14, 2022
eb33e30
feat: update pre-commit config
tutods Jul 14, 2022
4ba7802
feat: update pre-commit config
tutods Jul 14, 2022
81e909f
feat: start backend refactoring
tutods Jul 14, 2022
8720416
fix: remove console.log
tutods Jul 14, 2022
ab5a329
feat: refactoring backend
tutods Jul 14, 2022
e19b65e
chore: functions for css blur filters
f-morgado Jul 14, 2022
03ddeb3
Merge branch 'main' into feat-hide-cards-from-others
CatiaBarroco-xgeeks Jul 14, 2022
ad9b910
fix: pr conflits
CatiaBarroco-xgeeks Jul 14, 2022
5b1cadb
fix: backend tests
CatiaBarroco-xgeeks Jul 14, 2022
2b6a48d
fix: github conflits
CatiaBarroco-xgeeks Jul 14, 2022
60cfc74
fix: github conflits
CatiaBarroco-xgeeks Jul 14, 2022
e73331b
fix: github issues
f-morgado Jul 14, 2022
b5b9008
fix: dependencies
tutods Jul 14, 2022
0869d46
chore: improve replaceCard method
tutods Jul 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions backend/src/libs/utils/hideText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const hideText = (text: string): string => {
return text.replace(/[a-zA-Z0-9'#]/g, 'a');
};
126 changes: 103 additions & 23 deletions backend/src/modules/boards/services/get.board.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { Inject, Logger, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { LeanDocument, Model } from 'mongoose';
import User from 'src/modules/users/schemas/user.schema';
import { BOARDS_NOT_FOUND } from '../../../libs/exceptions/messages';
import { GetTeamServiceInterface } from '../../teams/interfaces/services/get.team.service.interface';
import * as Team from '../../teams/interfaces/types';
import { QueryType } from '../interfaces/findQuery';
import { GetBoardServiceInterface } from '../interfaces/services/get.board.service.interface';
import Board, { BoardDocument } from '../schemas/board.schema';
import BoardUser, { BoardUserDocument } from '../schemas/board.user.schema';
import { hideText } from '../../../libs/utils/hideText';

@Injectable()
export default class GetBoardServiceImpl implements GetBoardServiceInterface {
Expand Down Expand Up @@ -144,7 +146,69 @@ export default class GetBoardServiceImpl implements GetBoardServiceInterface {
return this.boardModel.findById(boardId).lean().exec();
}

async getBoard(boardId: string) {
hideInformation(board: LeanDocument<Board>, userId: string) {
return board.columns.forEach((column) =>
column.cards
.filter(
(card) =>
(card.createdBy as User)._id.toString() !== userId.toString(),
)
.forEach((card) => {
const cardUser = card.createdBy as User;

cardUser.firstName = hideText(cardUser.firstName);
cardUser.lastName = hideText(cardUser.lastName);
card.text = hideText(card.text);
card.comments
.filter(
(comment) =>
(comment.createdBy as User)._id.toString() !==
userId.toString(),
)
.forEach((comment) => {
const commentUser = comment.createdBy as User;

commentUser.firstName = hideText(commentUser.firstName);

commentUser.lastName = hideText(commentUser.lastName);

comment.text = hideText(comment.text);
});

card.items
.filter(
(item) =>
(item.createdBy as User)._id.toString() !== userId.toString(),
)
.forEach((item) => {
const cardItem = item.createdBy as User;

item.text = hideText(item.text);
cardItem.firstName = hideText(cardItem.firstName);
cardItem.lastName = hideText(cardItem.lastName);

item.comments
.filter(
(comment) =>
(comment.createdBy as User)._id.toString() !==
userId.toString(),
)
.forEach((comment) => {
const commentUserItem = comment.createdBy as User;

commentUserItem.firstName = hideText(
commentUserItem.firstName,
);
commentUserItem.lastName = hideText(commentUserItem.lastName);

comment.text = hideText(comment.text);
});
});
}),
);
}

async getBoardData(boardId: string) {
const board = await this.boardModel
.findById(boardId)
.populate({
Expand Down Expand Up @@ -188,30 +252,46 @@ export default class GetBoardServiceImpl implements GetBoardServiceInterface {
.lean({ virtuals: true })
.exec();

if (!board) return null;
return board;
}

if (board.isSubBoard) {
const mainBoard = await this.boardModel
.findOne({ dividedBoards: { $in: boardId } })
.select('dividedBoards team title')
.populate({
path: 'dividedBoards',
select: '_id title',
})
.populate({
path: 'team',
select: 'name users _id',
async getMainBoardData(boardId: string) {
const mainBoard = await this.boardModel
.findOne({ dividedBoards: { $in: boardId } })
.select('dividedBoards team title')
.populate({
path: 'dividedBoards',
select: '_id title',
})
.populate({
path: 'team',
select: 'name users _id',
populate: {
path: 'users',
select: 'user role',
populate: {
path: 'users',
select: 'user role',
populate: {
path: 'user',
select: 'firstName lastName joinedAt',
},
path: 'user',
select: 'firstName lastName joinedAt',
},
})
.lean({ virtuals: true })
.exec();
},
})
.lean({ virtuals: true })
.exec();

return mainBoard;
}

async getBoard(boardId: string, userId: string) {
const board = await this.getBoardData(boardId);

if (!board) return null;

if (board.hideCards) {
this.hideInformation(board, userId);
}

if (board.isSubBoard) {
const mainBoard = await this.getMainBoardData(boardId);
if (!mainBoard) return null;
return { board, mainBoardData: mainBoard };
}
Expand Down
3 changes: 3 additions & 0 deletions backend/src/modules/users/schemas/user.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export type UserDocument = User & mongoose.Document;
},
})
export default class User {
@Prop({ type: mongoose.Schema.Types.ObjectId })
_id!: mongoose.Schema.Types.ObjectId;

@Prop({ nullable: false })
firstName!: string;

Expand Down
21 changes: 21 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 22 additions & 2 deletions frontend/src/components/Board/Card/CardBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface CardBoardProps {
boardUser?: BoardUser;
maxVotes?: number;
isSubmited: boolean;
hideCards: boolean;
}

const CardBoard = React.memo<CardBoardProps>(
Expand All @@ -50,7 +51,8 @@ const CardBoard = React.memo<CardBoardProps>(
isMainboard,
boardUser,
maxVotes,
isSubmited
isSubmited,
hideCards
}) => {
const isCardGroup = card.items.length > 1;
const comments = useMemo(() => {
Expand All @@ -64,6 +66,7 @@ const CardBoard = React.memo<CardBoardProps>(
const [deleting, setDeleting] = useState(false);

const handleOpenComments = () => {
if (hideCards && card.createdBy?._id !== userId) return;
setOpenComments(!isCommentsOpened);
};

Expand Down Expand Up @@ -135,7 +138,16 @@ const CardBoard = React.memo<CardBoardProps>(
justify="between"
css={{ mb: '$8', '& > div': { zIndex: 2 } }}
>
<Text size="md" css={{ wordBreak: 'break-word' }}>
<Text
size="md"
css={{
wordBreak: 'break-word',
filter:
hideCards && card.createdBy?._id !== userId
? 'blur($sizes$6)'
: 'none'
}}
>
CatiaBarroco-xgeeks marked this conversation as resolved.
Show resolved Hide resolved
{card.text}
</Text>
{isSubmited && (
Expand All @@ -144,6 +156,7 @@ const CardBoard = React.memo<CardBoardProps>(
css={{ width: '$20', height: '$20' }}
/>
)}

{!isSubmited && (
<PopoverCardSettings
firstOne={false}
Expand All @@ -156,6 +169,9 @@ const CardBoard = React.memo<CardBoardProps>(
newPosition={0}
handleEditing={handleEditing}
handleDeleteCard={handleDeleting}
hideCards={hideCards}
userId={userId}
item={card}
/>
)}
</Flex>
Expand All @@ -174,6 +190,7 @@ const CardBoard = React.memo<CardBoardProps>(
userId={userId}
isMainboard={isMainboard}
isSubmited={isSubmited}
hideCards={hideCards}
/>
)}
<CardFooter
Expand All @@ -190,6 +207,7 @@ const CardBoard = React.memo<CardBoardProps>(
isCommentsOpened={isCommentsOpened}
boardUser={boardUser}
maxVotes={maxVotes}
hideCards={hideCards}
/>
</Flex>
)}
Expand All @@ -211,6 +229,8 @@ const CardBoard = React.memo<CardBoardProps>(
socketId={socketId}
cardItems={card.items}
isSubmited={isSubmited}
hideCards={hideCards}
userId={userId}
/>
)}
</Flex>
Expand Down
51 changes: 46 additions & 5 deletions frontend/src/components/Board/Card/CardFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface FooterProps {
isCommentsOpened?: boolean;
boardUser?: BoardUser;
maxVotes?: number;
hideCards: boolean;
}

const StyledButtonIcon = styled(Button, {
Expand Down Expand Up @@ -68,7 +69,8 @@ const CardFooter = React.memo<FooterProps>(
boardUser,
maxVotes,
setOpenComments,
isCommentsOpened
isCommentsOpened,
hideCards
}) => {
const { createdBy } = card;

Expand Down Expand Up @@ -98,6 +100,7 @@ const CardFooter = React.memo<FooterProps>(

const handleDeleteVote = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.stopPropagation();
if (hideCards && card.createdBy?._id !== userId) return;
if (votesOfUserInThisCard <= 0) return;
deleteVote.mutate({
boardId,
Expand All @@ -110,6 +113,7 @@ const CardFooter = React.memo<FooterProps>(

const handleAddVote = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.stopPropagation();
if (hideCards && card.createdBy?._id !== userId) return;
if (maxVotes && actualBoardVotes && actualBoardVotes >= maxVotes) return;
addVote.mutate({
boardId,
Expand All @@ -123,7 +127,16 @@ const CardFooter = React.memo<FooterProps>(
return (
<Flex align="center" justify={!anonymous ? 'between' : 'end'} gap="6">
{!anonymous && !teamName && (
<Flex gap="4" align="center">
<Flex
gap="4"
align="center"
css={{
filter:
hideCards && card.createdBy?._id !== userId
? 'blur($sizes$6)'
: 'none'
}}
>
<Avatar
size={20}
fallbackText={`${createdBy?.firstName[0]}${createdBy?.lastName[0]}`}
Expand All @@ -143,7 +156,16 @@ const CardFooter = React.memo<FooterProps>(
)}
{!isItem && comments && (
<Flex gap="10" align="center">
<Flex align="center" gap="2">
<Flex
align="center"
gap="2"
css={{
filter:
hideCards && card.createdBy?._id !== userId
? 'blur($sizes$6)'
: 'none'
}}
>
<StyledButtonIcon
onClick={handleAddVote}
disabled={!isMainboard || actualBoardVotes === maxVotes}
Expand All @@ -161,7 +183,17 @@ const CardFooter = React.memo<FooterProps>(
</Text>
</Flex>

<Flex align="center" gap="2" css={{ mr: '$10' }}>
<Flex
align="center"
gap="2"
css={{
mr: '$10',
filter:
hideCards && card.createdBy?._id !== userId
? 'blur($sizes$6)'
: 'none'
}}
>
<StyledButtonIcon
onClick={handleDeleteVote}
disabled={!isMainboard || votesOfUserInThisCard === 0}
Expand All @@ -170,7 +202,16 @@ const CardFooter = React.memo<FooterProps>(
</StyledButtonIcon>
</Flex>

<Flex align="center" gap="2">
<Flex
align="center"
gap="2"
css={{
filter:
hideCards && card.createdBy?._id !== userId
? 'blur($sizes$6)'
: 'none'
CatiaBarroco-xgeeks marked this conversation as resolved.
Show resolved Hide resolved
}}
>
<StyledButtonIcon onClick={setOpenComments}>
<Icon
name={
Expand Down
Loading