Add fixed bugs tab to versions

This commit is contained in:
Misode
2022-11-09 19:08:25 +01:00
parent 46347f1974
commit 6312dfbc71
8 changed files with 84 additions and 7 deletions

View File

@@ -17,5 +17,5 @@ export function Card({ title, overlay, link, children }: Props) {
return link === undefined
? <div class="card">{content}</div>
: <a class="card" href={link} >{content}</a>
: <a class="card" href={link} target={link.startsWith('https://') ? '_blank' : undefined}>{content}</a>
}

View File

@@ -0,0 +1,15 @@
import type { Bugfix } from '../../services/DataFetcher.js'
import { Badge } from '../Badge.jsx'
import { Card } from '../Card.jsx'
interface Props {
fix: Bugfix
}
export function Issue({ fix }: Props) {
return <Card overlay={fix.id} link={`https://bugs.mojang.com/browse/${fix.id}`}>
<div class="changelog-content">{fix.summary}</div>
<div class="badges-list">
{fix.categories.map(c => <Badge label={c} />)}
</div>
</Card>
}

View File

@@ -0,0 +1,23 @@
import { useLocale } from '../../contexts/Locale.jsx'
import { useAsync } from '../../hooks/useAsync.js'
import { fetchBugfixes } from '../../services/DataFetcher.js'
import type { VersionId } from '../../services/Schemas.js'
import { Issue } from './Issue.jsx'
interface Props {
version: string
}
export function IssueList({ version }: Props) {
const { locale } = useLocale()
const { value: issues, loading } = useAsync(() => fetchBugfixes(version as VersionId), [version])
return <div class="card-column">
{issues === undefined || loading ? <>
<span class="note">{locale('loading')}</span>
</> : issues.length === 0 ? <>
<span class="note">{locale('versions.fixes.no_results')}</span>
</> : <>
{issues?.map(issue => <Issue key={issue.id} fix={issue} />)}
</>}
</div>
}

View File

@@ -1,14 +1,15 @@
import { useMemo, useState } from 'preact/hooks'
import { useEffect, useMemo } from 'preact/hooks'
import { useLocale } from '../../contexts/index.js'
import { useAsync } from '../../hooks/useAsync.js'
import { useSearchParam } from '../../hooks/useSearchParam.js'
import type { VersionMeta } from '../../services/index.js'
import { fetchChangelogs, getArticleLink } from '../../services/index.js'
import { Giscus } from '../Giscus.js'
import { Octicon } from '../Octicon.js'
import { ChangelogList } from './ChangelogList.js'
import { VersionMetaData } from './index.js'
import { IssueList, VersionMetaData } from './index.js'
type Tab = 'changelog' | 'discussion'
const Tabs = ['changelog', 'discussion', 'fixes']
interface Props {
id: string,
@@ -17,7 +18,12 @@ interface Props {
export function VersionDetail({ id, version }: Props) {
const { locale } = useLocale()
const [tab, setTab] = useState<Tab>('changelog')
const [tab, setTab] = useSearchParam('tab')
useEffect(() => {
if (tab === undefined || !Tabs.includes(tab)) {
setTab(Tabs[0])
}
}, [tab])
const { value: changes } = useAsync(fetchChangelogs, [])
@@ -47,6 +53,7 @@ export function VersionDetail({ id, version }: Props) {
<div class="version-tabs">
<span class={tab === 'changelog' ? 'selected' : ''} onClick={() => setTab('changelog')}>{locale('versions.technical_changes')}</span>
<span class={tab === 'discussion' ? 'selected' : ''} onClick={() => setTab('discussion')}>{locale('versions.discussion')}</span>
<span class={tab === 'fixes' ? 'selected' : ''} onClick={() => setTab('fixes')}>{locale('versions.fixes')}</span>
{articleLink && <a href={articleLink} target="_blank">
{locale('versions.article')}
{Octicon.link_external}
@@ -55,6 +62,7 @@ export function VersionDetail({ id, version }: Props) {
<div class="version-tab">
{tab === 'changelog' && <ChangelogList changes={filteredChangelogs} defaultOrder="asc" />}
{tab === 'discussion' && <Giscus term={`version/${id}/`} />}
{tab === 'fixes' && <IssueList version={id} />}
</div>
</div>
</>

View File

@@ -1,6 +1,7 @@
export * from '../Badge.jsx'
export * from './ChangelogEntry.js'
export * from './ChangelogList.js'
export * from './IssueList.jsx'
export * from './VersionDetail.js'
export * from './VersionEntry.js'
export * from './VersionList.js'

View File

@@ -14,6 +14,8 @@ export function Versions({}: Props) {
const [selectedId] = useSearchParam('id')
const selected = (versions ?? []).find(v => v.id === selectedId)
const [tab] = useSearchParam('tab')
useTitle(
selected ? `Minecraft ${selected.name}` : 'Versions Explorer',
@@ -29,9 +31,9 @@ export function Versions({}: Props) {
{selectedId ? <>
<div class="navigation">
<BtnLink link="/versions/" icon="three_bars" label={locale('versions.all')} />
<BtnLink link={previousVersion ? `/versions/?id=${previousVersion.id}` : undefined}
<BtnLink link={previousVersion ? `/versions/?id=${previousVersion.id}${tab ? `&tab=${tab}` : ''}` : undefined}
icon="arrow_left" label={locale('versions.previous')} />
<BtnLink link={nextVersion ? `/versions/?id=${nextVersion.id}` : undefined}
<BtnLink link={nextVersion ? `/versions/?id=${nextVersion.id}${tab ? `&tab=${tab}` : ''}` : undefined}
icon="arrow_right" label={locale('versions.next')} swapped />
</div>
<VersionDetail id={selectedId} version={selected} />

View File

@@ -18,6 +18,7 @@ const latestVersion = __LATEST_VERSION__ ?? ''
const mcmetaUrl = 'https://raw.githubusercontent.com/misode/mcmeta'
const mcmetaTarballUrl = 'https://github.com/misode/mcmeta/tarball'
const changesUrl = 'https://raw.githubusercontent.com/misode/technical-changes'
const fixesUrl = 'https://raw.githubusercontent.com/misode/mcfixes'
type McmetaTypes = 'summary' | 'data' | 'data-json' | 'assets' | 'assets-json' | 'registries' | 'atlas'
@@ -235,6 +236,31 @@ export async function fetchChangelogs(): Promise<Change[]> {
}
}
export interface Bugfix {
id: string,
summary: string,
labels: string[],
status: string,
confirmation_status: string,
categories: string[],
priority: string,
fix_versions: string[],
creation_date: string,
resolution_date: string,
updated_date: string,
watches: number,
votes: number,
}
export async function fetchBugfixes(version: VersionId): Promise<Bugfix[]> {
try {
const fixes = await cachedFetch<Bugfix[]>(`${fixesUrl}/main/versions/${version}.json`, { refresh: true })
return fixes
} catch (e) {
throw new Error(`Error occured while fetching bugfixes: ${message(e)}`)
}
}
interface FetchOptions<D> {
decode?: (r: Response) => Promise<D>
refresh?: boolean

View File

@@ -205,6 +205,8 @@
"versions.resource_pack_format": "Resource pack format",
"versions.technical_changes": "Technical changes",
"versions.discussion": "Discussion",
"versions.fixes": "Fixed bugs",
"versions.fixes.no_results": "No fixes",
"versions.minecraft_versions": "Minecraft Versions",
"versions.latest_snapshot": "Latest snapshot",
"versions.latest_release": "Latest release",