Enable comment deletion on CommentDrawer (#460)

* Enable comment deletion on people and companies page

* Add storybook test
This commit is contained in:
Charles Bochet
2023-06-27 09:00:14 -07:00
committed by GitHub
parent c9038bb93a
commit a6b2fd75ba
12 changed files with 199 additions and 37 deletions

View File

@ -12,25 +12,29 @@ import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString';
type OwnProps = {
comment: Pick<CommentForDrawer, 'id' | 'author' | 'createdAt'>;
actionBar?: React.ReactNode;
};
const StyledContainer = styled.div`
align-items: center;
display: flex;
flex-direction: row;
gap: ${({ theme }) => theme.spacing(1)};
justify-content: flex-start;
justify-content: space-between;
padding: ${({ theme }) => theme.spacing(1)};
width: calc(100% - ${({ theme }) => theme.spacing(1)});
`;
const StyledLeftContainer = styled.div`
align-items: end;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
`;
const StyledName = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-size: 13px;
font-weight: 400;
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.regular};
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
@ -39,12 +43,9 @@ const StyledName = styled.div`
const StyledDate = styled.div`
color: ${({ theme }) => theme.font.color.light};
font-size: 12px;
font-weight: 400;
font-size: ${({ theme }) => theme.font.size.sm};
font-weight: ${({ theme }) => theme.font.weight.regular};
margin-left: ${({ theme }) => theme.spacing(1)};
padding-top: 1.5px;
`;
const StyledTooltip = styled(Tooltip)`
@ -62,7 +63,7 @@ const StyledTooltip = styled(Tooltip)`
padding: 8px;
`;
export function CommentHeader({ comment }: OwnProps) {
export function CommentHeader({ comment, actionBar }: OwnProps) {
const theme = useTheme();
const beautifiedCreatedAt = beautifyPastDateRelativeToNow(comment.createdAt);
const exactCreatedAt = beautifyExactDate(comment.createdAt);
@ -79,23 +80,28 @@ export function CommentHeader({ comment }: OwnProps) {
return (
<StyledContainer>
<Avatar
avatarUrl={avatarUrl}
size={theme.icon.size.md}
placeholder={capitalizedFirstUsernameLetter}
/>
<StyledName>{authorName}</StyledName>
{showDate && (
<>
<StyledDate id={`id-${commentId}`}>{beautifiedCreatedAt}</StyledDate>
<StyledTooltip
anchorSelect={`#id-${commentId}`}
content={exactCreatedAt}
clickable
noArrow
/>
</>
)}
<StyledLeftContainer>
<Avatar
avatarUrl={avatarUrl}
size={theme.icon.size.md}
placeholder={capitalizedFirstUsernameLetter}
/>
<StyledName>{authorName}</StyledName>
{showDate && (
<>
<StyledDate id={`id-${commentId}`}>
{beautifiedCreatedAt}
</StyledDate>
<StyledTooltip
anchorSelect={`#id-${commentId}`}
content={exactCreatedAt}
clickable
noArrow
/>
</>
)}
</StyledLeftContainer>
<div>{actionBar}</div>
</StyledContainer>
);
}

View File

@ -15,6 +15,7 @@ import { useCreateCommentMutation } from '~/generated/graphql';
import { GET_COMMENT_THREADS_BY_TARGETS } from '../services';
import { CommentThreadActionBar } from './CommentThreadActionBar';
import { CommentThreadItem } from './CommentThreadItem';
import { CommentThreadRelationPicker } from './CommentThreadRelationPicker';
@ -38,7 +39,7 @@ const StyledThreadItemListContainer = styled.div`
align-items: flex-start;
display: flex;
flex-direction: column-reverse;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(4)};
justify-content: flex-start;
@ -86,8 +87,18 @@ export function CommentThread({ commentThread }: OwnProps) {
return (
<StyledContainer>
<StyledThreadItemListContainer>
{commentThread.comments?.map((comment) => (
<CommentThreadItem key={comment.id} comment={comment} />
{commentThread.comments?.map((comment, index) => (
<CommentThreadItem
key={comment.id}
comment={comment}
actionBar={
index === 0 ? (
<CommentThreadActionBar commentThreadId={commentThread.id} />
) : (
<></>
)
}
/>
))}
</StyledThreadItemListContainer>
<CommentThreadRelationPicker commentThread={commentThread} />

View File

@ -0,0 +1,49 @@
import { getOperationName } from '@apollo/client/utilities';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { GET_COMPANIES } from '@/companies/services';
import { GET_PEOPLE } from '@/people/services';
import { IconTrash } from '@/ui/icons';
import { isRightDrawerOpenState } from '@/ui/layout/right-drawer/states/isRightDrawerOpenState';
import { useDeleteCommentThreadMutation } from '~/generated/graphql';
import { GET_COMMENT_THREADS_BY_TARGETS } from '../services';
const StyledContainer = styled.div`
color: ${({ theme }) => theme.font.color.tertiary};
cursor: pointer;
`;
type OwnProps = {
commentThreadId: string;
};
export function CommentThreadActionBar({ commentThreadId }: OwnProps) {
const theme = useTheme();
const [createCommentMutation] = useDeleteCommentThreadMutation();
const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState);
function deleteCommentThread() {
createCommentMutation({
variables: { commentThreadId },
refetchQueries: [
getOperationName(GET_COMPANIES) ?? '',
getOperationName(GET_PEOPLE) ?? '',
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
],
});
setIsRightDrawerOpen(false);
}
return (
<StyledContainer>
<IconTrash
size={theme.icon.size.sm}
stroke={theme.icon.stroke.md}
onClick={deleteCommentThread}
/>
</StyledContainer>
);
}

View File

@ -6,6 +6,7 @@ import { CommentHeader } from './CommentHeader';
type OwnProps = {
comment: CommentForDrawer;
actionBar?: React.ReactNode;
};
const StyledContainer = styled.div`
@ -14,6 +15,7 @@ const StyledContainer = styled.div`
flex-direction: column;
gap: ${({ theme }) => theme.spacing(1)};
justify-content: flex-start;
width: 100%;
`;
const StyledCommentBody = styled.div`
@ -28,10 +30,10 @@ const StyledCommentBody = styled.div`
text-align: left;
`;
export function CommentThreadItem({ comment }: OwnProps) {
export function CommentThreadItem({ comment, actionBar }: OwnProps) {
return (
<StyledContainer>
<CommentHeader comment={comment} />
<CommentHeader comment={comment} actionBar={actionBar} />
<StyledCommentBody>{comment.body}</StyledCommentBody>
</StyledContainer>
);

View File

@ -7,6 +7,7 @@ import { mockedUsersData } from '~/testing/mock-data/users';
import { getRenderWrapperForComponent } from '~/testing/renderWrappers';
import { CommentHeader } from '../CommentHeader';
import { CommentThreadActionBar } from '../CommentThreadActionBar';
const meta: Meta<typeof CommentHeader> = {
title: 'Modules/Comments/CommentHeader',
@ -114,3 +115,15 @@ export const WithLongUserName: Story = {
/>,
),
};
export const WithActionBar: Story = {
render: getRenderWrapperForComponent(
<CommentHeader
comment={{
...mockComment,
createdAt: DateTime.now().minus({ days: 2 }).toISO() ?? '',
}}
actionBar={<CommentThreadActionBar commentThreadId="test-id" />}
/>,
),
};