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

🤖 Release PR #3253

Merged
merged 13 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,15 @@
"contributions": [
"code"
]
},
{
"login": "dariusmihut",
"name": "dariusmihut",
"avatar_url": "https://avatars.githubusercontent.com/u/7417010?v=4",
"profile": "https://github.com/dariusmihut",
"contributions": [
"code"
]
}
],
"projectName": "community-platform",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ Thanks go to these wonderful people ([emoji key](https://allcontributors.org/doc
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/viracoding"><img src="https://avatars.githubusercontent.com/u/20618068?v=4?s=60" width="60px;" alt="viracoding"/><br /><sub><b>viracoding</b></sub></a><br /><a href="https://github.com/ONEARMY/community-platform/commits?author=viracoding" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Gashmoh"><img src="https://avatars.githubusercontent.com/u/24207256?v=4?s=60" width="60px;" alt="Gashmoh"/><br /><sub><b>Gashmoh</b></sub></a><br /><a href="https://github.com/ONEARMY/community-platform/commits?author=Gashmoh" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dariusmihut"><img src="https://avatars.githubusercontent.com/u/7417010?v=4?s=60" width="60px;" alt="dariusmihut"/><br /><sub><b>dariusmihut</b></sub></a><br /><a href="https://github.com/ONEARMY/community-platform/commits?author=dariusmihut" title="Code">💻</a></td>
</tr>
</tbody>
</table>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"format:style": "prettier --write '**/*.{md,json,js,tsx,ts}'",
"serve": "npx serve -s build",
"test": "yarn workspace oa-cypress start",
"test:components": "yarn workspace oa-components test",
"test:components": "yarn workspace oa-components test-ci",
"test:unit": "yarn build:themes && yarn build:components && env-cmd -e cra craco test --env=jsdom --runInBand --logHeapUsage --coverage --reporters=default --reporters=jest-junit",
"test:madge": "npx madge --circular --extensions ts,tsx ./ --exclude src/stores",
"storybook": "yarn workspace oa-components start",
Expand Down
3 changes: 2 additions & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"dev": "tsc --watch",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx src --color",
"new-component": "ts-node scripts/newComponent.ts",
"test": "vitest --coverage"
"test": "vitest",
"test-ci": "vitest --coverage"
},
"dependencies": {
"@emotion/react": "^11.10.6",
Expand Down
71 changes: 44 additions & 27 deletions packages/components/src/CommentItem/CommentItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ export interface CommentItemProps {
_id: string
_edited?: string
_created?: string
handleEdit?: (commentId: string, newCommentText: string) => void
handleCommentReply?: (commentId: string | null) => void
handleDelete?: (commentId: string) => Promise<void>
handleEdit?: (commentId: string, newCommentText: string) => void
handleEditRequest?: (commentId: string) => Promise<void>
}

Expand Down Expand Up @@ -49,6 +50,7 @@ export const CommentItem = (props: CommentItemProps) => {
handleDelete,
handleEdit,
isEditable,
handleCommentReply,
} = props

const date = formatDate(_edited || _created)
Expand Down Expand Up @@ -103,37 +105,52 @@ export const CommentItem = (props: CommentItemProps) => {
<Text sx={{ fontSize: 1 }}>{date}</Text>
</Flex>

{isEditable && (
<Flex
sx={{
flexGrow: 1,
gap: 2,
justifyContent: ['flex-start', 'flex-start', 'flex-end'],
opacity: 0.5,
width: ['100%', 'auto'],
':hover': { opacity: 1 },
}}
>
<Flex
sx={{
flexGrow: 1,
gap: 2,
justifyContent: ['flex-start', 'flex-start', 'flex-end'],
opacity: 0.5,
width: ['100%', 'auto'],
':hover': { opacity: 1 },
}}
>
{isEditable && (
<>
<Button
data-cy="CommentItem: edit button"
variant="outline"
small={true}
icon="edit"
onClick={() => onEditRequest(_id)}
>
edit
</Button>
<Button
data-cy="CommentItem: delete button"
variant={'outline'}
small={true}
icon="delete"
onClick={() => setShowDeleteModal(true)}
>
delete
</Button>
</>
)}
{typeof handleCommentReply === 'function' ? (
<Button
data-cy="CommentItem: edit button"
data-cy="CommentItem: reply button"
variant="outline"
small={true}
icon="edit"
onClick={() => onEditRequest(_id)}
icon="comment"
onClick={() => {
handleCommentReply && handleCommentReply(_id)
}}
>
edit
reply
</Button>
<Button
data-cy="CommentItem: delete button"
variant={'outline'}
small={true}
icon="delete"
onClick={() => setShowDeleteModal(true)}
>
delete
</Button>
</Flex>
)}
) : null}
</Flex>
</Flex>
<Text
data-cy="comment-text"
Expand Down
53 changes: 51 additions & 2 deletions packages/components/src/CommentList/CommentList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ export const Expandable: StoryFn<typeof CommentList> = () => (
)

export const WithNestedComments: StoryFn<typeof CommentList> = () => {
// TODO: This is a temporary solution to get nested comments to pass type check
const comments: any = [
const comments = [
fakeComment({
replies: [fakeComment(), fakeComment()],
}),
Expand All @@ -49,6 +48,56 @@ export const WithNestedComments: StoryFn<typeof CommentList> = () => {
)
}

export const WithNestedCommentsAndReplies: StoryFn<typeof CommentList> = () => {
const comments = [
fakeComment({
replies: [fakeComment(), fakeComment()],
}),
fakeComment(),
fakeComment(),
]

return (
<CommentList
supportReplies={true}
comments={comments}
setCommentBeingRepliedTo={() => {}}
handleDelete={() => Promise.resolve()}
handleEditRequest={() => Promise.resolve()}
handleEdit={() => Promise.resolve()}
onMoreComments={() => Promise.resolve()}
/>
)
}

export const WithNestedCommentsAndRepliesMaxDepthTwo: StoryFn<
typeof CommentList
> = () => {
const comments = [
fakeComment({
replies: [
fakeComment({
replies: [fakeComment()],
}),
],
}),
]

return (
<CommentList
supportReplies={true}
currentDepth={0}
maxDepth={2}
comments={comments}
setCommentBeingRepliedTo={() => {}}
handleDelete={() => Promise.resolve()}
handleEditRequest={() => Promise.resolve()}
handleEdit={() => Promise.resolve()}
onMoreComments={() => Promise.resolve()}
/>
)
}

const highlightedCommentList = createFakeComments(20, { isEditable: false })

export const Highlighted: StoryFn<typeof CommentList> = () => (
Expand Down
29 changes: 29 additions & 0 deletions packages/components/src/CommentList/CommentList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,33 @@ describe('CommentList', () => {

expect(screen.getAllByTestId('CommentList: item')).toHaveLength(5)
})

it('does not show reply once max depth is reached', () => {
const mockComments = [
fakeComment({
replies: [
fakeComment({
replies: [fakeComment()],
}),
],
}),
]

const screen = render(
<CommentList
currentDepth={0}
maxDepth={2}
supportReplies={true}
comments={mockComments}
replyForm={() => <></>}
setCommentBeingRepliedTo={() => {}}
handleEdit={mockHandleEdit}
handleEditRequest={mockHandleEditRequest}
handleDelete={mockHandleDelete}
onMoreComments={mockOnMoreComments}
/>,
)

expect(screen.getAllByText('reply')).toHaveLength(2)
})
})
25 changes: 25 additions & 0 deletions packages/components/src/CommentList/CommentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ export type CommentWithReplies = Comment & { replies?: Comment[] }
const MAX_COMMENTS = 5

export interface IProps {
supportReplies?: boolean
comments: CommentWithReplies[]
handleEdit: (_id: string, comment: string) => Promise<void>
handleEditRequest: () => Promise<void>
handleDelete: (_id: string) => Promise<void>
highlightedCommentId?: string
onMoreComments: () => void
setCommentBeingRepliedTo?: (commentId: string | null) => void
replyForm?: (commentId: string) => JSX.Element
currentDepth?: number
maxDepth?: number
}

export const CommentList = (props: IProps) => {
Expand All @@ -26,7 +31,15 @@ export const CommentList = (props: IProps) => {
highlightedCommentId,
handleEdit,
onMoreComments,
replyForm,
setCommentBeingRepliedTo,
supportReplies = false,
maxDepth = 9999,
currentDepth = 0,
} = props

const hasRepliesEnabled = supportReplies && currentDepth < maxDepth

const [moreComments, setMoreComments] = useState(1)
const shownComments = moreComments * MAX_COMMENTS

Expand All @@ -44,6 +57,11 @@ export const CommentList = (props: IProps) => {
}, 0)
}

const handleCommentReply =
hasRepliesEnabled && setCommentBeingRepliedTo
? setCommentBeingRepliedTo
: undefined

useEffect(() => {
if (!highlightedCommentId) return

Expand Down Expand Up @@ -81,20 +99,27 @@ export const CommentList = (props: IProps) => {
>
<CommentItem
{...comment}
handleCommentReply={handleCommentReply}
isUserVerified={!!comment.isUserVerified}
isEditable={!!comment.isEditable}
handleEditRequest={handleEditRequest}
handleDelete={handleDelete}
handleEdit={handleEdit}
/>
{replyForm && replyForm(comment._id)}
{comment.replies ? (
<Box sx={{ pt: 4, pl: 4 }}>
<CommentList
currentDepth={currentDepth + 1}
maxDepth={maxDepth}
comments={comment.replies}
supportReplies={hasRepliesEnabled}
handleEditRequest={handleEditRequest}
handleDelete={handleDelete}
handleEdit={handleEdit}
onMoreComments={handleMoreComments}
replyForm={replyForm}
setCommentBeingRepliedTo={setCommentBeingRepliedTo}
/>
</Box>
) : null}
Expand Down
4 changes: 3 additions & 1 deletion packages/components/src/CreateComment/CreateComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ export interface Props {
comment: string
placeholder?: string
userProfileType?: string
buttonLabel?: string
}

export const CreateComment = (props: Props) => {
const { comment, isLoggedIn, maxLength, onSubmit } = props
const userProfileType = props.userProfileType || 'member'
const placeholder = props.placeholder || 'Leave your questions or feedback...'
const buttonLabel = props.buttonLabel ?? 'Leave a comment'

const onChange = (newValue: string) => {
props.onChange && props?.onChange(newValue)
Expand Down Expand Up @@ -107,7 +109,7 @@ export const CreateComment = (props: Props) => {
onClick={() => onSubmit(comment)}
sx={{ marginTop: 3 }}
>
Leave a comment
{buttonLabel}
</Button>
</Flex>
</Flex>
Expand Down
Loading
Loading