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
22 changes: 14 additions & 8 deletions moon/apps/web/components/MrView/MRComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@ import type { MenuProps } from 'antd';
import { NotePlusIcon} from '@gitmono/ui/Icons'
import { formatDistance, fromUnixTime } from 'date-fns';
import LexicalContent from './rich-editor/LexicalContent';
import { useDeleteMrCommentDelete } from '@/hooks/useDeleteMrCommentDelete';
import { Conversation } from '@/pages/[org]/mr/[id]';

const Comment = ({ conv, fetchDetail }:any) => {
interface CommentProps {
conv: Conversation
id: string
}

const Comment = ({ conv, id }: CommentProps) => {

const { mutate: deleteComment } = useDeleteMrCommentDelete(id)
const handleDelete = () => {
deleteComment(conv.id)
}

const delete_comment = async () => {
await fetch(`/api/mr/comment/${conv.id}/delete`, {
method: 'POST',
});
};
const handleMenuClick: MenuProps['onClick'] = ({ key }) => {
if (key === '3') {
delete_comment()
fetchDetail()
handleDelete()
}
};

Expand Down
112 changes: 71 additions & 41 deletions moon/apps/web/components/MrView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
'use client'

import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { List, PaginationProps, Tag, Tabs, TabsProps } from 'antd';
import { formatDistance, fromUnixTime } from 'date-fns';
// import { MergeOutlined, PullRequestOutlined, CloseCircleOutlined } from '@ant-design/icons';
import { ChevronSelectIcon,AlarmIcon,ClockIcon} from '@gitmono/ui/Icons'
import { Link } from '@gitmono/ui/Link'
import { Heading } from './catalyst/heading';
import { usePostMrList } from '@/hooks/usePostMrList';
import { apiErrorToast } from '@/utils/apiErrorToast'
import { useScope } from '@/contexts/scope'

interface MrInfoItem {
link: string,
Expand All @@ -22,63 +24,81 @@ export default function MrView() {
const [numTotal, setNumTotal] = useState(0);
const [pageSize] = useState(10);
const [status, setStatus] = useState('open')
const [page, setPage] = useState(1);
const [isLoading, setIsLoading] = useState(false);
const { scope } = useScope()
const { mutate: fetchMrList } = usePostMrList();

const fetchData = useCallback(async (page: number, per_page: number) => {
try {
const res = await fetch(`/api/mr/list`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
const loadMrList = useCallback(() => {
setIsLoading(true);
fetchMrList(
{
data: {
pagination: {
page,
per_page: pageSize
},
body: JSON.stringify({
pagination: {
page: page,
per_page: per_page
},
additional: {
status: status
}
}),
});
const response = await res.json();
const data = response.data.data;

setMrList(data.items);
setNumTotal(data.total)
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error fetching data:', error);
}
}, [status]);
additional: {
status
}
}
},
{
onSuccess: (response) => {
const data = response.data;

setMrList(
data?.items?.map(item => ({
...item,
merge_timestamp: item.merge_timestamp ?? null
})) ?? []
);
setNumTotal(data?.total ?? 0);
},
onError: apiErrorToast,
onSettled: () => setIsLoading(false)
}
);
}, [page, pageSize, status, fetchMrList]);

useEffect(() => {
fetchData(1, pageSize);
}, [pageSize, status, fetchData]);
loadMrList();
}, [loadMrList]);

const getStatusTag = (status: string) => {
switch (status) {
const normalizedStatus = status.toLowerCase();

switch (normalizedStatus) {
case 'open':
return <Tag color="success">open</Tag>;
case 'merged':
return <Tag color="purple">merged</Tag>;
case 'closed':
return <Tag color="error">closed</Tag>;
default:
return null;
}
};

const getStatusIcon = (status: string) => {
switch (status) {
const normalizedStatus = status.toLowerCase();

switch (normalizedStatus) {
case 'open':
return <ChevronSelectIcon />;
case 'closed':
return <AlarmIcon />;
case 'merged':
return <ClockIcon />;
default:
return null;
}
};

const getDescription = (item: MrInfoItem) => {
switch (item.status) {
const normalizedStatus = item.status.toLowerCase();

switch (normalizedStatus) {
case 'open':
return `MergeRequest opened by Admin ${formatDistance(fromUnixTime(item.open_timestamp), new Date(), { addSuffix: true })} `;
case 'merged':
Expand All @@ -88,12 +108,14 @@ export default function MrView() {
return "";
}
case 'closed':
return (`MR ${item.link} closed by Admin ${formatDistance(fromUnixTime(item.updated_at), new Date(), { addSuffix: true })}`)
return (`MR ${item.link} closed by Admin ${formatDistance(fromUnixTime(item.updated_at), new Date(), { addSuffix: true })}`);
default:
return null;
}
}

const onChange: PaginationProps['onChange'] = (current, pageSize) => {
fetchData(current, pageSize);
const onChange: PaginationProps['onChange'] = (current) => {
setPage(current);
};

const tabsChange = (activeKey: string) => {
Expand All @@ -104,7 +126,7 @@ export default function MrView() {
}
}

const tab_items: TabsProps['items'] = [
const tab_items = useMemo(() => [
{
key: '1',
label: 'Open',
Expand All @@ -113,9 +135,7 @@ export default function MrView() {
key: '2',
label: 'Closed',
}
];

<AlarmIcon />
], []) as TabsProps['items'];

return (
<div className="m-4">
Expand All @@ -127,13 +147,23 @@ export default function MrView() {
className="w-full mt-2"
pagination={{ align: "center", pageSize: pageSize, total: numTotal, onChange: onChange }}
dataSource={mrList}
loading={isLoading}
renderItem={(item) => (
<List.Item>
<List.Item.Meta
avatar={
getStatusIcon(item.status)
}
title={<Link href={`/mr/${item.link}`}>{`${item.title}`} {getStatusTag(item.status)}</Link>}
title={
<Link href={{
pathname: `/${scope}/mr/${item.link}`,
query: {
title: item.title,
}
}}>
{`${item.title}`} {getStatusTag(item.status)}
</Link>
}
description={getDescription(item)}
/>
</List.Item>
Expand Down
18 changes: 18 additions & 0 deletions moon/apps/web/hooks/useDeleteMrCommentDelete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import type { DeleteApiMrCommentDeleteData, RequestParams } from '@gitmono/types'

export function useDeleteMrCommentDelete(id: string, params?: RequestParams) {
const queryClient = useQueryClient()

return useMutation<DeleteApiMrCommentDeleteData, Error, number>({
mutationKey: legacyApiClient.v1.deleteApiMrCommentDelete().baseKey,
mutationFn: (convId) =>
legacyApiClient.v1.deleteApiMrCommentDelete().request(convId, params),
onSuccess: (_data, _convId) => {
queryClient.invalidateQueries({
queryKey: legacyApiClient.v1.getApiMrDetail().requestKey(id),
})
},
})
}
11 changes: 11 additions & 0 deletions moon/apps/web/hooks/useGetMrDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useQuery } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import type { RequestParams } from '@gitmono/types'

export function useGetMrDetail(id: string, params?: RequestParams) {
return useQuery({
queryKey: legacyApiClient.v1.getApiMrDetail().requestKey(id),
queryFn: () => legacyApiClient.v1.getApiMrDetail().request(id, params),
enabled: !!id,
})
}
12 changes: 12 additions & 0 deletions moon/apps/web/hooks/useGetMrFilesChanged.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQuery } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import type { RequestParams } from '@gitmono/types'
import type { GetApiMrFilesChangedData } from '@gitmono/types/generated'

export function useGetMrFilesChanged(id: string, params?: RequestParams) {
return useQuery<GetApiMrFilesChangedData>({
queryKey: legacyApiClient.v1.getApiMrFilesChanged().requestKey(id),
queryFn: () => legacyApiClient.v1.getApiMrFilesChanged().request(id, params),
enabled: !!id,
})
}
17 changes: 17 additions & 0 deletions moon/apps/web/hooks/usePostMrClose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import type { PostApiMrCloseData, RequestParams } from '@gitmono/types'

export function usePostMrClose(link: string, params?: RequestParams) {
const queryClient = useQueryClient()

return useMutation<PostApiMrCloseData, Error>({
mutationKey: legacyApiClient.v1.postApiMrClose().requestKey(link),
mutationFn: () => legacyApiClient.v1.postApiMrClose().request(link, params),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: legacyApiClient.v1.getApiMrDetail().requestKey(link),
})
},
})
}
18 changes: 18 additions & 0 deletions moon/apps/web/hooks/usePostMrComment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import type { SaveCommentRequest, PostApiMrCommentData, RequestParams } from '@gitmono/types'

export function usePostMrComment(link: string, params?: RequestParams) {
const queryClient = useQueryClient()

return useMutation<PostApiMrCommentData, Error, SaveCommentRequest>({
mutationKey: legacyApiClient.v1.postApiMrComment().requestKey(link),
mutationFn: (data) =>
legacyApiClient.v1.postApiMrComment().request(link, data, params),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: legacyApiClient.v1.getApiMrDetail().requestKey(link),
})
},
})
}
11 changes: 11 additions & 0 deletions moon/apps/web/hooks/usePostMrList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// hooks/usePostApiMrList.ts
import { useMutation } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import { PageParamsMRStatusParams, RequestParams, PostApiMrListData } from '@gitmono/types'

export function usePostMrList() {
return useMutation<PostApiMrListData, Error, { data: PageParamsMRStatusParams; params?: RequestParams }>({
mutationFn: ({ data, params }) =>
legacyApiClient.v1.postApiMrList().request(data, params),
})
}
19 changes: 19 additions & 0 deletions moon/apps/web/hooks/usePostMrMerge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import type { PostApiMrMergeData, RequestParams } from '@gitmono/types'

export function usePostMrMerge(link: string, params?: RequestParams) {
const queryClient = useQueryClient()

return useMutation<PostApiMrMergeData, Error, void>({
mutationKey: legacyApiClient.v1.postApiMrMerge().requestKey(link),
mutationFn: () =>
legacyApiClient.v1.postApiMrMerge().request(link, params),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: legacyApiClient.v1.getApiMrDetail().requestKey(link),
})
},
})
}

17 changes: 17 additions & 0 deletions moon/apps/web/hooks/usePostMrReopen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { legacyApiClient } from '@/utils/queryClient'
import type { PostApiMrReopenData, RequestParams } from '@gitmono/types'

export function usePostMrReopen(link: string, params?: RequestParams) {
const queryClient = useQueryClient()

return useMutation<PostApiMrReopenData, Error>({
mutationKey: legacyApiClient.v1.postApiMrReopen().requestKey(link),
mutationFn: () => legacyApiClient.v1.postApiMrReopen().request(link, params),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: legacyApiClient.v1.getApiMrDetail().requestKey(link),
})
},
})
}
Loading