Skip to content
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
5 changes: 3 additions & 2 deletions moon/apps/web/components/Issues/IssueDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ interface IssueDetail {
}
interface Conversation {
id: number
user_id: number
conv_type: string
comment: string
created_at: number
created_at: number,
updated_at: number,
username: string,
}

interface detailRes {
Expand Down
42 changes: 42 additions & 0 deletions moon/apps/web/components/MrView/CloseItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { ConditionalWrap } from '@gitmono/ui'
import { useGetOrganizationMember } from '@/hooks/useGetOrganizationMember'
import { Conversation } from '@/pages/[org]/mr/[id]'
import { MemberHovercard } from '../InlinePost/MemberHovercard'
import { MemberAvatar } from '../MemberAvatar'
import { UserLinkByName } from './components/UserLinkByName'
import HandleTime from './components/HandleTime'


interface CloseItemProps {
conv: Conversation
}
const CloseItem = ({ conv }: CloseItemProps) => {
const { data: member } = useGetOrganizationMember({ username: conv.username })

return (
<>
<div className='flex items-center space-x-2'>
<div className='cursor-pointer'>
<ConditionalWrap
condition={true}
wrap={(c) => (
<MemberHovercard username={conv?.username}>
<UserLinkByName username={conv?.username} className='relative'>
{c}
</UserLinkByName>
</MemberHovercard>
)}
>
{member ? <MemberAvatar member={member} size='sm' /> : 'Avatar not found'}
</ConditionalWrap>
</div>
<div>{conv.comment}</div>
<div className='text-sm text-gray-500 hover:text-gray-700'>
<HandleTime created_at={conv.created_at}/>
</div>
</div>
</>
)
}

export default CloseItem
120 changes: 53 additions & 67 deletions moon/apps/web/components/MrView/MRComment.tsx
Original file line number Diff line number Diff line change
@@ -1,85 +1,71 @@
// import { MoreOutlined } from '@ant-design/icons';
import { NotePlusIcon } from '@gitmono/ui/Icons'
import type { MenuProps } from 'antd'
import { Card, Dropdown } from 'antd/lib'
import { formatDistance, fromUnixTime } from 'date-fns'
import { getMarkdownExtensions } from '@gitmono/editor'
import { useDeleteIssueComment } from '@/hooks/issues/useDeleteIssueComment'
import { useDeleteMrCommentDelete } from '@/hooks/useDeleteMrCommentDelete'
import { Conversation } from '@/pages/[org]/mr/[id]'
import { RichTextRenderer } from '@/components/RichTextRenderer'
import { useMemo } from 'react'
import { ConditionalWrap, UIText } from '@gitmono/ui'
import { MemberHovercard } from '../InlinePost/MemberHovercard'
import { MemberAvatar } from '../MemberAvatar'
import { useGetOrganizationMember } from '@/hooks/useGetOrganizationMember'
import { KebabHorizontalIcon } from '@primer/octicons-react'
import { UserLinkByName } from './components/UserLinkByName'
import HandleTime from './components/HandleTime'

interface CommentProps {
conv: Conversation
id: string
whoamI: string
Comment thread
Ceron-CSS marked this conversation as resolved.
}

const Comment = ({ conv, id, whoamI }: CommentProps) => {
const { mutate: deleteComment } = useDeleteMrCommentDelete(id)
const { mutate: deleteIssueComment } = useDeleteIssueComment(id)
const handleDelete = () => {
switch (whoamI) {
case 'issue':
deleteIssueComment(conv.id)
break
case 'mr':
deleteComment(conv.id)
break
default:
return
}
}

const handleMenuClick: MenuProps['onClick'] = ({ key }) => {
if (key === '3') {
handleDelete()
}
}

const items: MenuProps['items'] = [
{
label: 'Edit',
key: '1',
disabled: true
},
{
label: 'Hide',
key: '2',
disabled: true
},
{
type: 'divider'
},
{
label: 'Delete',
key: '3',
danger: true
}
]
const menuProps = {
items,
onClick: handleMenuClick
}

const time = formatDistance(fromUnixTime(conv.created_at), new Date(), { addSuffix: true })
const Comment = ({ conv }: CommentProps) => {
const { data: member } = useGetOrganizationMember({ username: conv.username })

const extensions = useMemo(() => getMarkdownExtensions({ linkUnfurl: {} }), [])

return (
<Card
size='small'
title={'Mega commented ' + time}
style={{ border: '1px solid #d1d9e0' }}
extra={
<Dropdown menu={menuProps} trigger={['click']}>
<NotePlusIcon />
</Dropdown>
}
>
<div className='prose copyable-text'>
<div className='overflow-hidden rounded-lg border border-gray-300 bg-white'>
<div className='flex items-center justify-between border-b border-gray-300 py-2 px-4'>
<div className='flex items-center space-x-3'>
<div className='cursor-pointer'>
<ConditionalWrap
condition={true}
wrap={(c) => (
<MemberHovercard username={conv?.username}>
<UserLinkByName username={conv?.username} className='relative'>
{c}
</UserLinkByName>
</MemberHovercard>
)}
>
{ member ? <MemberAvatar member={member} size='sm'/> : "Avatar not found"}
</ConditionalWrap>
</div>
<div className='cursor-pointer'>
<ConditionalWrap
condition={true}
wrap={(children) => (
<MemberHovercard username={conv?.username}>
<UserLinkByName username={conv?.username}>{children}</UserLinkByName>
</MemberHovercard>
)}
>
<UIText element='span' primary weight='font-medium' className='break-anywhere line-clamp-1'>
{conv?.username || 'username not found'}
</UIText>
</ConditionalWrap>
</div>
<div className='text-sm text-gray-500 hover:text-gray-700'>
<HandleTime created_at={conv.created_at}/>
</div>
</div>
<button className='hover:text-blue-700'>
<KebabHorizontalIcon />
</button>
</div>

<div className='prose copyable-text p-3'>
<RichTextRenderer content={conv.comment} extensions={extensions} />
</div>
</Card>
</div>
)
}

Expand Down
21 changes: 21 additions & 0 deletions moon/apps/web/components/MrView/MergedItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Conversation } from '@/pages/[org]/mr/[id]'
import HandleTime from './components/HandleTime'

interface MergedItemProps {
conv: Conversation
}
const MergedItem = ({ conv }: MergedItemProps) => {

return (
<>
<div className='flex items-center space-x-2'>
<div>Merged via the queue into main</div>
<div className='text-sm text-gray-500 hover:text-gray-700'>
<HandleTime created_at={conv.created_at}/>
</div>
</div>
</>
)
}

export default MergedItem
42 changes: 42 additions & 0 deletions moon/apps/web/components/MrView/ReopenItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { ConditionalWrap } from '@gitmono/ui'
import { useGetOrganizationMember } from '@/hooks/useGetOrganizationMember'
import { Conversation } from '@/pages/[org]/mr/[id]'
import { MemberHovercard } from '../InlinePost/MemberHovercard'
import { MemberAvatar } from '../MemberAvatar'
import { UserLinkByName } from './components/UserLinkByName'
import HandleTime from './components/HandleTime'


interface ReopenItemProps {
conv: Conversation
}
const ReopenItem = ({ conv }: ReopenItemProps) => {
const { data: member } = useGetOrganizationMember({ username: conv.username })

return (
<>
<div className='flex items-center space-x-2'>
<div className='cursor-pointer'>
<ConditionalWrap
condition={true}
wrap={(c) => (
<MemberHovercard username={conv?.username}>
<UserLinkByName username={conv?.username} className='relative'>
{c}
</UserLinkByName>
</MemberHovercard>
)}
>
{member ? <MemberAvatar member={member} size='sm' /> : 'Avatar not found'}
</ConditionalWrap>
</div>
<div>{conv.comment}</div>
<div className='text-sm text-gray-500 hover:text-gray-700'>
<HandleTime created_at={conv.created_at}/>
</div>
</div>
</>
)
}

export default ReopenItem
19 changes: 10 additions & 9 deletions moon/apps/web/components/MrView/TimelineItems.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react'
import '@primer/primitives/dist/css/functional/themes/light.css'
import { BaseStyles, ThemeProvider, Timeline } from '@primer/react'
import { FeedPullRequestClosedIcon, CommentIcon, FeedMergedIcon, IssueReopenedIcon } from '@primer/octicons-react'
import { FeedPullRequestClosedIcon, CommentIcon, FeedMergedIcon, FeedPullRequestOpenIcon } from '@primer/octicons-react'
import MRComment from '@/components/MrView/MRComment';
import { formatDistance, fromUnixTime } from 'date-fns';
import { MRDetail } from '@/pages/[org]/mr/[id]';
import CloseItem from './CloseItem';
import ReopenItem from './ReopenItem';
import MergedItem from './MergedItem';

interface TimelineItemProps {
badge?: React.ReactNode
Expand Down Expand Up @@ -69,19 +71,18 @@ const TimelineItems: React.FC<{ mrDetail?: MRDetail, id: string }> = ({ mrDetail
break;
case 'Merged':
icon = <FeedMergedIcon size={24} className="text-purple-500" />;
children =
'Merged via the queue into main ' +
formatDistance(fromUnixTime(conv.created_at), new Date(), { addSuffix: true });
children = <MergedItem conv={conv} />;
isOver = true;
break;
case 'Closed':
icon = <FeedPullRequestClosedIcon size={24} className="text-red-500" />;
children = conv.comment;
icon = <FeedPullRequestClosedIcon size={24} className="text-red-600" />;
children = <CloseItem conv={conv}/>;
isOver = true;
break;
case 'Reopen':
icon = <IssueReopenedIcon />;
children = conv.comment;
icon = <FeedPullRequestOpenIcon size={24}
className = "text-green-500"/>
children = <ReopenItem conv={conv}/>;
break;
}

Expand Down
25 changes: 25 additions & 0 deletions moon/apps/web/components/MrView/components/HandleTime.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { format, formatDistance, fromUnixTime } from 'date-fns'
import { Tooltip } from '@gitmono/ui'

interface HandleTimeProps {
created_at: number
}

const HandleTime = ({ created_at }: HandleTimeProps) => {
const time = formatDistance(fromUnixTime(created_at), new Date(), { addSuffix: true })
const formatTimestamp = (timestamp: number) => {
const date = timestamp > 1e12 ? fromUnixTime(Math.floor(timestamp / 1000)) : fromUnixTime(timestamp)

return format(date, 'yyyy-MM-dd HH:mm:ss')
}

return (
<>
<Tooltip label={formatTimestamp(created_at)}>
<div className='underline'>{time}</div>
</Tooltip>
</>
)
}

export default HandleTime
18 changes: 18 additions & 0 deletions moon/apps/web/components/MrView/components/UserLinkByName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Link, LinkProps } from '@gitmono/ui/Link'
import { useScope } from '@/contexts/scope'

export function UserLinkByName({
username,
children,
...linkProps
}: Omit<LinkProps, 'href'> & { username: string; children: React.ReactNode }) {
const { scope } = useScope()

if(!username) return <>{children}</>

return (
<Link {...linkProps} href={`/${scope}/people/${username}`}>
{children}
</Link>
)
}
4 changes: 2 additions & 2 deletions moon/apps/web/hooks/issues/useGetIssueDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { legacyApiClient } from '@/utils/queryClient'

interface conversations {
id: number
user_id: number
conv_type: string
comment: string
created_at: number
updated_at: number
username: string
}

interface raw {
Expand All @@ -22,7 +22,7 @@ interface raw {

interface issueDetail {
status: string
conversations: { id: number; user_id: number; conv_type: string; comment: string; created_at: number }[]
conversations: conversations[]
title: string
}

Expand Down
Loading