-
Notifications
You must be signed in to change notification settings - Fork 1
fix(web): 版本历史与列表加载失败时展示错误提示;移除 emoji 改用 Lucide 图标 #15
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
Changes from all commits
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 |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| import { | ||
| AlertCircle, | ||
| Bot, | ||
| Calendar, | ||
| Check, | ||
|
|
@@ -185,22 +186,24 @@ export default function GeneDetail() { | |
| const { slug } = useParams<{ slug: string }>(); | ||
| const [gene, setGene] = useState<Gene | null>(null); | ||
| const [versions, setVersions] = useState<GeneVersion[]>([]); | ||
| const [versionsError, setVersionsError] = useState<string | null>(null); | ||
| const [error, setError] = useState(''); | ||
|
|
||
| useEffect(() => { | ||
| if (!slug) return; | ||
| getGene(slug) | ||
| .then(setGene) | ||
| .catch(() => setError('找不到该基因')); | ||
| setVersionsError(null); | ||
| getGeneVersions(slug) | ||
| .then(setVersions) | ||
| .catch(() => {}); | ||
| .catch(() => setVersionsError('版本历史加载失败,请刷新重试')); | ||
| }, [slug]); | ||
|
Comment on lines
192
to
201
|
||
|
|
||
| if (error) { | ||
| return ( | ||
| <div className="max-w-6xl mx-auto px-4 py-20 text-center"> | ||
| <div className="text-5xl mb-4">😵</div> | ||
| <AlertCircle className="w-14 h-14 mx-auto mb-4 text-muted" /> | ||
| <p className="text-xl text-gray-900 mb-2">{error}</p> | ||
| <Link to="/browse" className="text-primary hover:underline"> | ||
| 返回浏览 | ||
|
|
@@ -390,7 +393,11 @@ export default function GeneDetail() { | |
| <TabsContent value="reviews">{slug && <ReviewList slug={slug} />}</TabsContent> | ||
|
|
||
| <TabsContent value="versions"> | ||
| <VersionHistory versions={versions} slug={gene.slug} /> | ||
| {versionsError ? ( | ||
| <p className="text-sm text-red-600">{versionsError}</p> | ||
| ) : ( | ||
| <VersionHistory versions={versions} slug={gene.slug} /> | ||
| )} | ||
| </TabsContent> | ||
| </Tabs> | ||
| </div> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,6 +20,7 @@ export default function GenomeBrowse() { | |||||||
| const [total, setTotal] = useState(0); | ||||||||
| const [totalPages, setTotalPages] = useState(0); | ||||||||
| const [loading, setLoading] = useState(true); | ||||||||
| const [listError, setListError] = useState<string | null>(null); | ||||||||
| const { isAdmin } = useAuth(); | ||||||||
|
|
||||||||
| const q = searchParams.get('q') || ''; | ||||||||
|
|
@@ -42,6 +43,7 @@ export default function GenomeBrowse() { | |||||||
|
|
||||||||
| useEffect(() => { | ||||||||
| setLoading(true); | ||||||||
| setListError(null); | ||||||||
| listGenomes({ | ||||||||
| q: q || undefined, | ||||||||
| category: category || undefined, | ||||||||
|
|
@@ -58,6 +60,7 @@ export default function GenomeBrowse() { | |||||||
| .catch(() => { | ||||||||
| setGenomes([]); | ||||||||
| setTotal(0); | ||||||||
|
||||||||
| setTotal(0); | |
| setTotal(0); | |
| setTotalPages(0); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -132,16 +132,18 @@ export default function GenomeDetail() { | |
| const { slug } = useParams<{ slug: string }>(); | ||
| const [genome, setGenome] = useState<Genome | null>(null); | ||
| const [versions, setVersions] = useState<GeneVersion[]>([]); | ||
| const [versionsError, setVersionsError] = useState<string | null>(null); | ||
| const [error, setError] = useState(''); | ||
|
|
||
| useEffect(() => { | ||
| if (!slug) return; | ||
| getGenome(slug) | ||
| .then(setGenome) | ||
| .catch(() => setError('找不到该基因组')); | ||
| setVersionsError(null); | ||
| getGenomeVersions(slug) | ||
| .then(setVersions) | ||
| .catch(() => {}); | ||
| .catch(() => setVersionsError('版本历史加载失败,请刷新重试')); | ||
| }, [slug]); | ||
|
Comment on lines
138
to
147
|
||
|
|
||
| if (error) { | ||
|
|
@@ -263,7 +265,11 @@ export default function GenomeDetail() { | |
| </TabsContent> | ||
|
|
||
| <TabsContent value="versions"> | ||
| <VersionHistory versions={versions} slug={genome.slug} entityType="genome" /> | ||
| {versionsError ? ( | ||
| <p className="text-sm text-red-600">{versionsError}</p> | ||
| ) : ( | ||
| <VersionHistory versions={versions} slug={genome.slug} entityType="genome" /> | ||
| )} | ||
| </TabsContent> | ||
| </Tabs> | ||
| </div> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| import { ArrowRight, CheckCircle, Search } from 'lucide-react'; | ||
| import { ArrowRight, Bot, CheckCircle, Dna, Plug, Rocket, Search } from 'lucide-react'; | ||
| import { useEffect, useState } from 'react'; | ||
| import { Link, useNavigate } from 'react-router-dom'; | ||
| import { type Gene, listGenes } from '@/api/client'; | ||
|
|
@@ -80,14 +80,26 @@ export default function Home() { | |
| </button> | ||
| </div> | ||
| </form> | ||
| <div className="mt-6 flex justify-center gap-4 text-sm text-white/60 flex-wrap"> | ||
| <span>🧬 {totalGenes > 0 ? `${totalGenes} 个基因` : '基因持续上新'}</span> | ||
| <div className="mt-6 flex justify-center items-center gap-4 text-sm text-white/60 flex-wrap"> | ||
| <span className="flex items-center gap-1.5"> | ||
| <Dna className="w-4 h-4 shrink-0" /> | ||
| {totalGenes > 0 ? `${totalGenes} 个基因` : '基因持续上新'} | ||
| </span> | ||
| <span>•</span> | ||
| <span>🚀 L0-L3 学习协议</span> | ||
| <span className="flex items-center gap-1.5"> | ||
| <Rocket className="w-4 h-4 shrink-0" /> | ||
| L0-L3 学习协议 | ||
| </span> | ||
| <span>•</span> | ||
| <span>🔌 多平台兼容</span> | ||
| <span className="flex items-center gap-1.5"> | ||
| <Plug className="w-4 h-4 shrink-0" /> | ||
| 多平台兼容 | ||
| </span> | ||
| <span>•</span> | ||
| <span>🤖 AI Curator 自动审核</span> | ||
| <span className="flex items-center gap-1.5"> | ||
| <Bot className="w-4 h-4 shrink-0" /> | ||
| AI Curator 自动审核 | ||
| </span> | ||
| </div> | ||
|
Comment on lines
+83
to
103
|
||
| </div> | ||
| </section> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,6 +20,7 @@ export default function TemplateBrowse() { | |||||||
| const [total, setTotal] = useState(0); | ||||||||
| const [totalPages, setTotalPages] = useState(0); | ||||||||
| const [loading, setLoading] = useState(true); | ||||||||
| const [listError, setListError] = useState<string | null>(null); | ||||||||
| const { isAdmin } = useAuth(); | ||||||||
|
|
||||||||
| const q = searchParams.get('q') || ''; | ||||||||
|
|
@@ -42,6 +43,7 @@ export default function TemplateBrowse() { | |||||||
|
|
||||||||
| useEffect(() => { | ||||||||
| setLoading(true); | ||||||||
| setListError(null); | ||||||||
| listTemplates({ | ||||||||
| q: q || undefined, | ||||||||
| category: category || undefined, | ||||||||
|
|
@@ -58,6 +60,7 @@ export default function TemplateBrowse() { | |||||||
| .catch(() => { | ||||||||
| setTemplates([]); | ||||||||
| setTotal(0); | ||||||||
|
||||||||
| setTotal(0); | |
| setTotal(0); | |
| setTotalPages(0); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -142,16 +142,18 @@ export default function TemplateDetail() { | |
| const { slug } = useParams<{ slug: string }>(); | ||
| const [template, setTemplate] = useState<AgentTemplate | null>(null); | ||
| const [versions, setVersions] = useState<GeneVersion[]>([]); | ||
| const [versionsError, setVersionsError] = useState<string | null>(null); | ||
| const [error, setError] = useState(''); | ||
|
|
||
| useEffect(() => { | ||
| if (!slug) return; | ||
| getTemplate(slug) | ||
| .then(setTemplate) | ||
| .catch(() => setError('找不到该 AI 员工模板')); | ||
| setVersionsError(null); | ||
| getTemplateVersions(slug) | ||
| .then(setVersions) | ||
| .catch(() => {}); | ||
| .catch(() => setVersionsError('版本历史加载失败,请刷新重试')); | ||
| }, [slug]); | ||
|
Comment on lines
148
to
157
|
||
|
|
||
| if (error) { | ||
|
|
@@ -322,7 +324,11 @@ export default function TemplateDetail() { | |
| </TabsContent> | ||
|
|
||
| <TabsContent value="versions"> | ||
| <VersionHistory versions={versions} slug={template.slug} entityType="template" /> | ||
| {versionsError ? ( | ||
| <p className="text-sm text-red-600">{versionsError}</p> | ||
| ) : ( | ||
| <VersionHistory versions={versions} slug={template.slug} entityType="template" /> | ||
| )} | ||
| </TabsContent> | ||
| </Tabs> | ||
| </div> | ||
|
|
||
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.
联邦搜索失败时只清空了
federatedItems/total,但没有重置federatedSources。如果用户上一次联邦搜索成功过,失败后 Header 仍可能显示旧的来源计数(本地/ClawHub),与当前错误状态不一致。建议在该catch分支里同时将federatedSources重置为 0 计数(必要时也可重置totalPages)。