-
Notifications
You must be signed in to change notification settings - Fork 1
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
OUT-1380 | Comment box designs #624
base: feature/M11
Are you sure you want to change the base?
Changes from all commits
c0d1729
65e94f0
1c7c45d
aaaf6e7
5218550
6299d1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,14 +2,17 @@ | |
|
||
import { CommentCardContainer } from '@/app/detail/ui/styledComponent' | ||
import { CopilotAvatar } from '@/components/atoms/CopilotAvatar' | ||
import AttachmentLayout from '@/components/AttachmentLayout' | ||
import { MAX_UPLOAD_LIMIT } from '@/constants/attachments' | ||
import { selectAuthDetails } from '@/redux/features/authDetailsSlice' | ||
import { selectTaskBoard } from '@/redux/features/taskBoardSlice' | ||
import { selectTaskDetails } from '@/redux/features/taskDetailsSlice' | ||
import { CreateComment } from '@/types/dto/comment.dto' | ||
import { getMentionsList } from '@/utils/getMentionList' | ||
import { deleteEditorAttachmentsHandler, uploadImageHandler } from '@/utils/inlineImage' | ||
import { ArrowUpward } from '@mui/icons-material' | ||
import { IconButton, InputAdornment, Stack } from '@mui/material' | ||
import { useEffect, useState } from 'react' | ||
import { Box, IconButton, InputAdornment, Stack } from '@mui/material' | ||
import { useEffect, useRef, useState } from 'react' | ||
import { useSelector } from 'react-redux' | ||
import { Tapwrite } from 'tapwrite' | ||
|
||
|
@@ -23,7 +26,7 @@ | |
const [isListOrMenuActive, setIsListOrMenuActive] = useState(false) | ||
const { assigneeSuggestions } = useSelector(selectTaskDetails) | ||
const { tokenPayload } = useSelector(selectAuthDetails) | ||
const { assignee } = useSelector(selectTaskBoard) | ||
const { assignee, token, activeTask } = useSelector(selectTaskBoard) | ||
const currentUserId = tokenPayload?.internalUserId ?? tokenPayload?.clientId | ||
const currentUserDetails = assignee.find((el) => el.id === currentUserId) | ||
|
||
|
@@ -75,8 +78,45 @@ | |
return () => { | ||
window.removeEventListener('keydown', handleKeyDown) | ||
} | ||
}, [detail, isListOrMenuActive]) // Depend on detail to ensure the latest state is captured | ||
|
||
const uploadFn = token | ||
? async (file: File) => { | ||
if (activeTask) { | ||
const fileUrl = await uploadImageHandler(file, token ?? '', activeTask.workspaceId, task_id) | ||
return fileUrl | ||
} | ||
} | ||
: undefined | ||
const [isDragging, setIsDragging] = useState(false) | ||
const dragCounter = useRef(0) | ||
|
||
const handleDragOver = (e: React.DragEvent) => { | ||
e.preventDefault() | ||
if (!isDragging) { | ||
setIsDragging(true) | ||
} | ||
} | ||
|
||
const handleDragEnter = () => { | ||
dragCounter.current += 1 | ||
if (!isDragging) { | ||
setIsDragging(true) | ||
} | ||
} | ||
|
||
const handleDragLeave = () => { | ||
dragCounter.current -= 1 | ||
Comment on lines
+102
to
+109
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please explain the need for dragCounter here... don't really catch the reason for it. Don't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dragcounter is used because there could be multiple events firing while dragging, the events could be of same type or different type, for example drag enter, drag leave or other. To track the multiple events and stop flickering. The reason there are multiple events is because of nested dom structure. Lets say, there is a parent container and multiple child containers nested inside, if the drag is left from the innermost child container, then drag leave is fired causing setIsDragging to be false but since the drag is not out of the parent container, there is flickering. |
||
if (dragCounter.current === 0) { | ||
setIsDragging(false) | ||
} | ||
} | ||
|
||
const handleDrop = (e: React.DragEvent) => { | ||
e.preventDefault() | ||
setIsDragging(false) | ||
dragCounter.current = 0 | ||
} | ||
return ( | ||
<Stack direction="row" columnGap={2} alignItems="flex-start"> | ||
<CopilotAvatar | ||
|
@@ -91,15 +131,19 @@ | |
/> | ||
<CommentCardContainer | ||
sx={{ | ||
backgroundColor: (theme) => `${theme.color.base.white}`, | ||
backgroundColor: (theme) => (isDragging ? theme.color.background.bgCommentDrag : theme.color.base.white), | ||
wordBreak: 'break-word', | ||
}} | ||
onDragOver={handleDragOver} | ||
onDragEnter={handleDragEnter} | ||
onDragLeave={handleDragLeave} | ||
onDrop={handleDrop} | ||
> | ||
<Tapwrite | ||
content={detail} | ||
getContent={setDetail} | ||
placeholder="Leave a comment..." | ||
suggestions={assigneeSuggestions} | ||
// suggestions={assigneeSuggestions} enable this for mentions | ||
editorClass="tapwrite-comment-input" | ||
hardbreak | ||
onActiveStatusChange={(prop) => { | ||
|
@@ -109,31 +153,40 @@ | |
parentContainerStyle={{ | ||
width: '100%', | ||
height: '100%', | ||
maxWidth: '600px', | ||
maxWidth: '566px', | ||
display: 'flex', | ||
flexDirection: 'column', | ||
}} | ||
uploadFn={uploadFn} | ||
deleteEditorAttachments={(url) => deleteEditorAttachmentsHandler(url, token ?? '', task_id, null)} | ||
attachmentLayout={AttachmentLayout} | ||
addAttachmentButton | ||
maxUploadLimit={MAX_UPLOAD_LIMIT} | ||
endButtons={ | ||
<Box | ||
sx={{ | ||
alignSelf: 'center', | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
}} | ||
> | ||
<IconButton | ||
onClick={handleSubmit} | ||
sx={{ | ||
backgroundColor: '#000', | ||
borderRadius: '4px', | ||
padding: '5px', | ||
'&:hover': { bgcolor: '#000' }, | ||
height: '24px', | ||
width: '24px', | ||
}} | ||
> | ||
<ArrowUpward sx={{ color: '#ffffff', fontSize: '18px' }} /> | ||
</IconButton> | ||
</Box> | ||
} | ||
/> | ||
<InputAdornment | ||
position="end" | ||
sx={{ | ||
alignSelf: 'flex-end', | ||
display: 'flex', | ||
alignItems: 'flex-end', | ||
}} | ||
> | ||
<IconButton | ||
onClick={() => handleSubmit()} // Call handleSubmit on button click | ||
sx={{ | ||
backgroundColor: '#000', | ||
borderRadius: '4px', | ||
padding: '5px', | ||
'&:hover': { bgcolor: '#000' }, | ||
}} | ||
> | ||
<ArrowUpward sx={{ color: '#ffffff', fontSize: '18px' }} /> | ||
</IconButton> | ||
</InputAdornment> | ||
</CommentCardContainer> | ||
</Stack> | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8024,10 +8024,10 @@ tapable@^2.2.0: | |
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" | ||
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== | ||
|
||
[email protected].82: | ||
version "1.1.82" | ||
resolved "https://registry.yarnpkg.com/tapwrite/-/tapwrite-1.1.82.tgz#9056cef00520fd2b75b4739715faf4771397f269" | ||
integrity sha512-qkQ1sLe2FuisYukFiJ7BosT6pmtSSZdwuQvFOZ51zbrhyFc0TAdHhd7ufBvEoeM3YhiyYg/CqO1/UAjw3DQwCQ== | ||
[email protected].83: | ||
version "1.1.83" | ||
resolved "https://registry.yarnpkg.com/tapwrite/-/tapwrite-1.1.83.tgz#7dab06fd3cf500856ae8ff4eab5b881502ec3328" | ||
integrity sha512-UgimYSjtgR8c2tq+hmdyKaPG3cXYmCPwsgJ35J7cnI74J+yYygNne1fXk6yqT/O3KfLYimM58BsAvGSSLVs9AQ== | ||
dependencies: | ||
re-resizable "^6.10.0" | ||
tippy.js "^6.3.7" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should work if token is string | undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think this is possible because this is passed directly to tapwrite prop
uploadFn
which expects something like(file : File) => promise('string' | undefined')
and not(" " | (file : File) => promise('string' | undefined'))