From ccdcaac21135712a708a43c83480c0b925f6b019 Mon Sep 17 00:00:00 2001 From: liuyangjuncong20202570 Date: Fri, 4 Jul 2025 18:48:05 +0800 Subject: [PATCH] feat(UI):api dockiing & replace the icons --- moon/apps/web/components/Issues/IssueList.tsx | 28 +- .../web/components/Issues/IssueNewPage.tsx | 4 +- .../web/components/Issues/IssuesContent.tsx | 192 ++++++++---- .../apps/web/components/Issues/Pagenation.tsx | 9 +- .../web/components/Issues/utils/consts.ts | 29 +- .../web/components/Issues/utils/store.tsx | 2 +- moon/apps/web/components/MrView/index.tsx | 284 +++++++++++------- .../apps/web/hooks/issues/useGetIssueLists.ts | 1 + moon/apps/web/hooks/usePostMrList.ts | 9 +- 9 files changed, 354 insertions(+), 204 deletions(-) diff --git a/moon/apps/web/components/Issues/IssueList.tsx b/moon/apps/web/components/Issues/IssueList.tsx index fc509ba6f..ab1339eef 100644 --- a/moon/apps/web/components/Issues/IssueList.tsx +++ b/moon/apps/web/components/Issues/IssueList.tsx @@ -1,7 +1,7 @@ import React, { forwardRef, memo, ReactNode, useRef, useState } from 'react' import { useAtomValue } from 'jotai' -import { SyncOrganizationMember } from '@gitmono/types/index' +import { LabelItem, SyncOrganizationMember } from '@gitmono/types/index' import { Button, ChevronDownIcon, @@ -16,7 +16,6 @@ import { import { DropdownMenu } from '@gitmono/ui/DropdownMenu' import { MenuItem } from '@gitmono/ui/Menu' -import { Label } from '@/components/Issues/IssuesContent' import { darkModeAtom } from '@/components/Issues/utils/store' import { SubjectCommand } from '@/components/Subject/SubjectCommand' import { BreadcrumbTitlebar } from '@/components/Titlebar/BreadcrumbTitlebar' @@ -119,7 +118,7 @@ export const DropdownItemwithAvatar = ({ ) } -export const DropdownItemwithLabel = ({ classname, label }: { classname?: string; label: Label }) => { +export const DropdownItemwithLabel = ({ classname, label }: { classname?: string; label: LabelItem }) => { return (
{label.name} - {label.remarks} + {label.description}
) } @@ -201,7 +200,7 @@ export const Dropdown = ({ dropdownItem, isChosen, onOpen, - open, + // open, inside }: { name: string @@ -217,6 +216,14 @@ export const Dropdown = ({ // const [sort] = useAtom(sortAtom({ scope, filter: 'sortPicker' })) const isSearching = query.length > 0 const ref = useRef(null) + const [open, setOpen] = useState(false) + + const handleOpenChange = (isOpen: boolean) => { + setOpen(isOpen) + if (onOpen) { + onOpen(isOpen) // 把状态变化通知给父组件 + } + } const DropdownSearch = () => (
@@ -252,7 +259,7 @@ export const Dropdown = ({ {isChosen ? ( handleOpenChange(open)} key={name} align='end' desktop={{ width: 'w-72 max-h-[50vh] overflow-auto bg-white' }} @@ -265,8 +272,11 @@ export const Dropdown = ({ }, { type: 'item', - label: , - onSelect: (e) => e.preventDefault() + label: + // onSelect: (e) => { + // e.preventDefault() + // onOpen?.(false) + // } // className: 'sticky top-10 z-50 bg-white' }, { type: 'separator' }, @@ -290,6 +300,8 @@ export const Dropdown = ({ handleOpenChange(open)} desktop={{ width: 'w-72' }} items={[ { diff --git a/moon/apps/web/components/Issues/IssueNewPage.tsx b/moon/apps/web/components/Issues/IssueNewPage.tsx index 2970b0474..7ba42ab16 100644 --- a/moon/apps/web/components/Issues/IssueNewPage.tsx +++ b/moon/apps/web/components/Issues/IssueNewPage.tsx @@ -74,7 +74,7 @@ export default function IssueNewPage() { const labels: ItemInput[] = useMemo( () => tags.map((i) => ({ - text: i.remarks, + text: i.description, leadingVisual: () => (
{ - map.set(i.remarks, i) + map.set(i.description, i) }) return map }, []) diff --git a/moon/apps/web/components/Issues/IssuesContent.tsx b/moon/apps/web/components/Issues/IssuesContent.tsx index d6530527a..de17c99eb 100644 --- a/moon/apps/web/components/Issues/IssuesContent.tsx +++ b/moon/apps/web/components/Issues/IssuesContent.tsx @@ -1,17 +1,16 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react' +import { CheckIcon, IssueClosedIcon, IssueOpenedIcon, SkipIcon } from '@primer/octicons-react' import { useInfiniteQuery } from '@tanstack/react-query' import { formatDistance, fromUnixTime } from 'date-fns' import { useAtom } from 'jotai' -import { SyncOrganizationMember as Member, PostApiIssueListData } from '@gitmono/types/generated' import { - Button, - ChatBubbleIcon, - CheckCircleFilledFlushIcon, - ChevronDownIcon, - CircleFilledCloseIcon, - OrderedListIcon -} from '@gitmono/ui' + LabelItem, + SyncOrganizationMember as Member, + PageParamsListPayload, + PostApiIssueListData +} from '@gitmono/types/generated' +import { Button, ChatBubbleIcon, ChevronDownIcon, OrderedListIcon } from '@gitmono/ui' import { Link } from '@gitmono/ui/Link' // import { MenuItem } from '@gitmono/ui/Menu' @@ -56,6 +55,10 @@ export interface Item { updated_at: number } +type ItemsType = NonNullable['items'] + +export type AdditionType = NonNullable['additional'] + export interface Label { id: string name: string @@ -73,7 +76,7 @@ export function IssuesContent({ searching }: Props) { const [status, _setStatus] = useAtom(filterAtom({ scope, part: 'issue' })) - const [issueList, setIssueList] = useState([]) + const [issueList, setIssueList] = useState([]) const [loading, setLoading] = useState(false) @@ -81,29 +84,34 @@ export function IssuesContent({ searching }: Props) { const [sort, setSort] = useAtom(sortAtom({ scope, filter: 'sortPicker' })) - const orderAtom = useMemo(() => atomWithWebStorage(`${scope}:issue-order`, 'Newest'), [scope]) + const orderAtom = useMemo( + () => atomWithWebStorage(`${scope}:issue-order`, { sort: 'Created On', time: 'Newest' }), + [scope] + ) + const labelAtom = useMemo(() => atomWithWebStorage(`${scope}:issue-label`, []), [scope]) + + const [order, setOrder] = useAtom(orderAtom) - const [order, _setOrder] = useAtom(orderAtom) + const [label, setLabel] = useAtom(labelAtom) const { members } = useSyncedMembers() const MemberConfig: MenuConfig[] = [ { key: 'Author', - isChosen: (item) => item.user.id === sort['Author'], + isChosen: (item) => item.user.username === sort['Author'], onSelectFactory: (item: Member) => (e: Event) => { e.preventDefault() - if (item.user.id === sort['Author']) { + if (item.user.username === sort['Author']) { fetchData(1, pageSize) setSort({ ...sort, Author: '' }) } else { - setIssueList(issueList.filter((i) => i.link === sort['Author'])) setSort({ ...sort, - Author: item.user.id + Author: item.user.username }) } }, @@ -112,21 +120,19 @@ export function IssuesContent({ searching }: Props) { }, { key: 'Assignees', - isChosen: (item: Member) => item.user.id === sort['Assignees'], + isChosen: (item: Member) => item.user.username === sort['Assignees'], onSelectFactory: (item: Member) => (e: Event) => { e.preventDefault() - if (item.user.id === sort['Assignees']) { + if (item.user.username === sort['Assignees']) { fetchData(1, pageSize) - setSort({ ...sort, Assignees: '' }) } else { - setIssueList(issueList.filter((i) => i.link === sort['Assignees'])) setSort({ ...sort, - Assignees: item.user.id + Assignees: item.user.username }) } }, @@ -135,47 +141,83 @@ export function IssuesContent({ searching }: Props) { } ] - const LabelConfig: MenuConfig