diff --git a/COMMIT_EDITMSG b/COMMIT_EDITMSG index 97422f0..6dd12d1 100644 --- a/COMMIT_EDITMSG +++ b/COMMIT_EDITMSG @@ -1,14 +1,12 @@ -Handle missing ZXDB releases/downloads schema gracefully +Show downloads even without releases rows -Prevent runtime crashes when `releases`, `downloads`, or related lookup tables -(`releasetypes`, `schemetypes`, `sourcetypes`, `casetypes`) are absent in the -connected ZXDB MySQL database. +Add synthetic release groups in getEntryById so downloads +are displayed even when there are no matching rows in +`releases` for a given entry. Group by `release_seq`, +attach downloads, and sort groups for stable order. -- Repo: gate releases/downloads queries behind a schema capability check using - `information_schema.tables`; if missing, skip queries and return empty arrays. -- Keeps entry detail page functional on legacy/minimal DB exports while fully - utilizing rich data when available. +This fixes cases like /zxdb/entries/1 where `downloads` +exist for the entry but `releases` is empty, resulting in +no downloads shown in the UI. -Refs: runtime error "Table 'zxdb.releasetypes' doesn't exist" - -Signed-off-by: Junie@quinn \ No newline at end of file +Signed-off-by: Junie@devbox diff --git a/src/app/zxdb/entries/[id]/EntryDetail.tsx b/src/app/zxdb/entries/[id]/EntryDetail.tsx index f244b3c..71c8f0b 100644 --- a/src/app/zxdb/entries/[id]/EntryDetail.tsx +++ b/src/app/zxdb/entries/[id]/EntryDetail.tsx @@ -26,6 +26,23 @@ export type EntryDetailData = { comments: string | null; type: { id: number; name: string }; }[]; + // Flat downloads by entry_id + downloadsFlat?: { + id: number; + link: string; + size: number | null; + md5: string | null; + comments: string | null; + isDemo: boolean; + type: { id: number; name: string }; + language: { id: string | null; name: string | null }; + machinetype: { id: number | null; name: string | null }; + scheme: { id: string | null; name: string | null }; + source: { id: string | null; name: string | null }; + case: { id: string | null; name: string | null }; + year: number | null; + releaseSeq: number; + }[]; releases?: { releaseSeq: number; type: { id: string | null; name: string | null }; @@ -173,6 +190,71 @@ export default function EntryDetailClient({ data }: { data: EntryDetailData }) {
| Type | +Link | +Size | +MD5 | +Flags | +Details | +Comments | +
|---|---|---|---|---|---|---|
| {d.type.name} | ++ {isHttp ? ( + {d.link} + ) : ( + {d.link} + )} + | +{typeof d.size === "number" ? d.size.toLocaleString() : "-"} | +{d.md5 ?? "-"} |
+
+
+ {d.isDemo ? Demo : null}
+ {d.scheme.name ? {d.scheme.name} : null}
+ {d.source.name ? {d.source.name} : null}
+ {d.case.name ? {d.case.name} : null}
+
+ |
+
+
+ {d.language.name && (
+ {d.language.name}
+ )}
+ {d.machinetype.name && (
+ {d.machinetype.name}
+ )}
+ {typeof d.year === "number" ? {d.year} : null}
+ rel #{d.releaseSeq}
+
+ |
+ {d.comments ?? ""} | +
| Type | -Link | -Size | -MD5 | -Flags | -Details | -
|---|---|---|---|---|---|
| {d.type.name} | -- {isHttp ? ( - {d.link} - ) : ( - {d.link} - )} - | -{d.size != null ? new Intl.NumberFormat().format(d.size) : "-"} | -{d.md5 ?? "-"} |
-
-
- {d.isDemo && Demo}
- {d.language.name && {d.language.name}}
- {d.machinetype.name && {d.machinetype.name}}
-
- |
-
-
- {d.scheme.name && {d.scheme.name}}
- {d.source.name && {d.source.name}}
- {d.case.name && {d.case.name}}
- {d.year && {d.year}}
-
- {d.comments && {d.comments} }
- |
-