fix: project center — repo selector dropdown, fix Gitea tab, clean UI
Some checks failed
Deploy Admin Frontend / build-and-deploy (push) Failing after 8s

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
WangDL 2026-05-24 20:03:29 +08:00
parent e85ffc1bcf
commit 9ed1a64929

View File

@ -1,5 +1,5 @@
import { useState } from 'react' import { useState } from 'react'
import { Table, Tag, Tabs, Typography, Card, Row, Col, Spin } from 'antd' import { Table, Tag, Tabs, Typography, Card, Row, Col, Select, Space, Spin } from 'antd'
import { CodeOutlined, RocketOutlined } from '@ant-design/icons' import { CodeOutlined, RocketOutlined } from '@ant-design/icons'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { api } from '@/services/http-client' import { api } from '@/services/http-client'
@ -41,12 +41,25 @@ export default function ProjectCenter() {
enabled: tab === 'runners', enabled: tab === 'runners',
}) })
const repoOptions = (repos || []).map((r: any) => ({ label: r.fullName, value: r.fullName }))
const RepoSelector = () => (
<Select
placeholder="选择仓库"
value={selectedRepo}
onChange={setSelectedRepo}
options={repoOptions}
style={{ width: 280 }}
showSearch
filterOption={(input, option) => (option?.label as string)?.toLowerCase().includes(input.toLowerCase())}
allowClear
/>
)
const repoColumns = [ const repoColumns = [
{ title: '仓库', dataIndex: 'fullName', width: 200, render: (n: string) => <a onClick={() => { setSelectedRepo(n); setTab('issues') }}>{n}</a> }, { title: '仓库', dataIndex: 'fullName', width: 200, render: (n: string) => <a onClick={() => { setSelectedRepo(n); setTab('issues') }}>{n}</a> },
{ title: '描述', dataIndex: 'description', width: 200, ellipsis: true, render: (d: string) => d || '-' }, { title: '描述', dataIndex: 'description', width: 200, ellipsis: true, render: (d: string) => d || '-' },
{ title: 'Issues', dataIndex: 'openIssues', width: 70 }, { title: 'Issues', dataIndex: 'openIssues', width: 70 },
{ title: 'PRs', dataIndex: 'openPulls', width: 70 },
{ title: '里程碑', dataIndex: 'milestones', width: 70 },
{ title: 'Stars', dataIndex: 'stars', width: 60 }, { title: 'Stars', dataIndex: 'stars', width: 60 },
{ title: '分支', dataIndex: 'defaultBranch', width: 80, render: (b: string) => <Tag>{b}</Tag> }, { title: '分支', dataIndex: 'defaultBranch', width: 80, render: (b: string) => <Tag>{b}</Tag> },
{ title: '更新', dataIndex: 'updatedAt', width: 100, render: (d: string) => d ? new Date(d).toLocaleDateString() : '-' }, { title: '更新', dataIndex: 'updatedAt', width: 100, render: (d: string) => d ? new Date(d).toLocaleDateString() : '-' },
@ -70,44 +83,59 @@ export default function ProjectCenter() {
<Tabs activeKey={tab} onChange={setTab} items={[ <Tabs activeKey={tab} onChange={setTab} items={[
{ {
key: 'repos', label: '仓库列表', key: 'repos', label: '仓库列表',
children: <Table dataSource={repos || []} columns={repoColumns} rowKey="id" loading={isLoading} size="small" pagination={false} scroll={{ x: 900 }} />, children: <Table dataSource={repos || []} columns={repoColumns} rowKey="id" loading={isLoading} size="small" pagination={false} scroll={{ x: 700 }} />,
}, },
{ {
key: 'issues', label: `Issues${selectedRepo ? ` · ${selectedRepo}` : ''}`, key: 'issues', label: 'Issues',
children: selectedRepo ? ( children: (
<Table dataSource={issues || []} columns={issueColumns} rowKey="id" size="small" pagination={{ pageSize: 30 }} scroll={{ x: 700 }} /> <div>
) : <Text type="secondary"></Text>, <Space style={{ marginBottom: 12 }}><RepoSelector /></Space>
{selectedRepo ? (
<Table dataSource={issues || []} columns={issueColumns} rowKey="id" size="small" pagination={{ pageSize: 30 }} scroll={{ x: 700 }} />
) : <Text type="secondary"></Text>}
</div>
),
}, },
{ {
key: 'milestones', label: '里程碑', key: 'milestones', label: '里程碑',
children: selectedRepo ? ( children: (
<Row gutter={[16, 16]}> <div>
{(milestones || []).map((m: any) => ( <Space style={{ marginBottom: 12 }}><RepoSelector /></Space>
<Col xs={24} sm={12} lg={8} key={m.id}> {selectedRepo ? (
<Card size="small" title={m.title}> <Row gutter={[16, 16]}>
<Text type="secondary">{m.description || '无描述'}</Text> {(milestones || []).map((m: any) => (
<br /> <Col xs={24} sm={12} lg={8} key={m.id}>
<Tag color={m.state === 'open' ? 'blue' : 'default'}>{m.state}</Tag> <Card size="small" title={m.title}>
{m.due_on && <Tag> {new Date(m.due_on).toLocaleDateString()}</Tag>} <Text type="secondary">{m.description || '无描述'}</Text>
</Card> <br />
</Col> <Tag color={m.state === 'open' ? 'blue' : 'default'}>{m.state}</Tag>
))} {m.due_on && <Tag> {new Date(m.due_on).toLocaleDateString()}</Tag>}
</Row> </Card>
) : <Text type="secondary"></Text>, </Col>
))}
</Row>
) : <Text type="secondary"></Text>}
</div>
),
}, },
{ {
key: 'releases', label: 'Release', key: 'releases', label: 'Release',
children: selectedRepo ? ( children: (
<Table <div>
dataSource={releases || []} rowKey="id" size="small" pagination={false} <Space style={{ marginBottom: 12 }}><RepoSelector /></Space>
columns={[ {selectedRepo ? (
{ title: '标签', dataIndex: 'tag_name', width: 120, render: (t: string) => <Tag color="blue"><RocketOutlined /> {t}</Tag> }, <Table
{ title: '标题', dataIndex: 'name', width: 250, ellipsis: true }, dataSource={releases || []} rowKey="id" size="small" pagination={false}
{ title: '发布者', dataIndex: ['author', 'login'], width: 100 }, columns={[
{ title: '发布时间', dataIndex: 'published_at', width: 120, render: (d: string) => d ? new Date(d).toLocaleDateString() : '-' }, { title: '标签', dataIndex: 'tag_name', width: 120, render: (t: string) => <Tag color="blue"><RocketOutlined /> {t}</Tag> },
]} { title: '标题', dataIndex: 'name', width: 250, ellipsis: true },
/> { title: '发布者', dataIndex: ['author', 'login'], width: 100 },
) : <Text type="secondary"></Text>, { title: '发布时间', dataIndex: 'published_at', width: 120, render: (d: string) => d ? new Date(d).toLocaleDateString() : '-' },
]}
/>
) : <Text type="secondary"></Text>}
</div>
),
}, },
{ {
key: 'runners', label: 'Runner 状态', key: 'runners', label: 'Runner 状态',
@ -123,7 +151,7 @@ export default function ProjectCenter() {
/> />
) : <Spin />, ) : <Spin />,
}, },
tab === 'gitea' ? undefined : { {
key: 'gitea', label: 'Gitea 面板', key: 'gitea', label: 'Gitea 面板',
children: ( children: (
<div style={{ width: '100%', height: 'calc(100vh - 200px)' }}> <div style={{ width: '100%', height: 'calc(100vh - 200px)' }}>
@ -131,8 +159,7 @@ export default function ProjectCenter() {
</div> </div>
), ),
}, },
].filter(Boolean) as any} ]} />
/>
</div> </div>
) )
} }