Tighten issue route typing
- Remove the remaining Oxlint warnings in the issues route UI - Make promise handling explicit in navigation and refresh paths - Keep the issue snapshot shape aligned with the fields the UI reads
This commit is contained in:
parent
ce1fb16b76
commit
fb29e0179e
4 changed files with 38 additions and 18 deletions
|
|
@ -2,10 +2,34 @@ export type IssueStatus = 'open' | 'in_progress' | 'resolved' | 'dismissed';
|
|||
export type IssueEntityType = 'track' | 'album' | 'artist';
|
||||
export type IssuePriority = 'low' | 'normal' | 'high';
|
||||
|
||||
export interface IssueTrackRow extends Record<string, unknown> {
|
||||
bitrate?: string | number;
|
||||
disc_number?: string | number;
|
||||
duration?: string | number;
|
||||
format?: string;
|
||||
id?: string | number;
|
||||
title?: string;
|
||||
track_number?: string | number;
|
||||
}
|
||||
|
||||
export interface IssueSnapshot {
|
||||
[key: string]: unknown;
|
||||
title?: string;
|
||||
album_track_count?: string | number;
|
||||
bitrate?: string | number;
|
||||
bpm?: string | number;
|
||||
disc_number?: string | number;
|
||||
duration?: string | number;
|
||||
file_path?: string;
|
||||
format?: string;
|
||||
genres?: string[];
|
||||
label?: string;
|
||||
name?: string;
|
||||
record_type?: string;
|
||||
title?: string;
|
||||
track_count?: string | number;
|
||||
tracks?: IssueTrackRow[];
|
||||
track_number?: string | number;
|
||||
year?: string | number;
|
||||
artist_name?: string;
|
||||
album_title?: string;
|
||||
thumb_url?: string;
|
||||
|
|
@ -16,14 +40,7 @@ export interface IssueSnapshot {
|
|||
spotify_track_id?: string;
|
||||
artist_id?: string | number;
|
||||
album_id?: string | number;
|
||||
track_number?: string | number;
|
||||
duration?: string | number;
|
||||
format?: string;
|
||||
bitrate?: string | number;
|
||||
bpm?: string | number;
|
||||
quality?: string;
|
||||
file_path?: string;
|
||||
tracks?: Array<Record<string, unknown>>;
|
||||
artist_musicbrainz_id?: string;
|
||||
musicbrainz_release_id?: string;
|
||||
musicbrainz_recording_id?: string;
|
||||
|
|
@ -44,8 +61,8 @@ export interface IssueRecord {
|
|||
category: string;
|
||||
title: string;
|
||||
description?: string | null;
|
||||
status: IssueStatus | string;
|
||||
priority: 'low' | 'normal' | 'high' | string;
|
||||
status: string;
|
||||
priority: string;
|
||||
snapshot_data: IssueSnapshot | string | null;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
launchAlbumWishlistWorkflow,
|
||||
} from '@/platform/workflows/album-workflows';
|
||||
|
||||
import type { IssueRecord } from '../-issues.types';
|
||||
import type { IssueRecord, IssueTrackRow } from '../-issues.types';
|
||||
|
||||
import { deleteIssue, issueDetailQueryOptions, updateIssue } from '../-issues.api';
|
||||
import {
|
||||
|
|
@ -439,7 +439,7 @@ export function IssueDetailModal({
|
|||
);
|
||||
}
|
||||
|
||||
function renderTrackListing(trackRows: Array<Record<string, unknown>>) {
|
||||
function renderTrackListing(trackRows: IssueTrackRow[]) {
|
||||
const nodes: ReactNode[] = [];
|
||||
let lastDisc: number | null = null;
|
||||
const hasMultiDisc = trackRows.some((track) => Number(track.disc_number || 1) > 1);
|
||||
|
|
|
|||
|
|
@ -369,7 +369,10 @@ function getReportIssueFormError(errors: Array<unknown>): string {
|
|||
if (!error) return '';
|
||||
if (typeof error === 'string') return error;
|
||||
if (error instanceof Error) return error.message;
|
||||
return String(error);
|
||||
if (typeof error === 'number' || typeof error === 'boolean' || typeof error === 'bigint') {
|
||||
return String(error);
|
||||
}
|
||||
return 'Unable to submit this issue';
|
||||
}
|
||||
|
||||
function notify(message: string, type: 'success' | 'error' | 'warning' | 'info' = 'info') {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export function IssuesPage() {
|
|||
const params = Route.useSearch();
|
||||
|
||||
const clearIssueSelection = () => {
|
||||
navigate({
|
||||
void navigate({
|
||||
to: Route.fullPath,
|
||||
search: (prev) => normalizeIssuesSearch({ ...prev, issueId: undefined }),
|
||||
replace: true,
|
||||
|
|
@ -63,7 +63,7 @@ function IssueBoard() {
|
|||
|
||||
useEffect(() => {
|
||||
const handleRefresh = () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['issues'] });
|
||||
void queryClient.invalidateQueries({ queryKey: ['issues'] });
|
||||
};
|
||||
|
||||
window.addEventListener(REFRESH_EVENT, handleRefresh);
|
||||
|
|
@ -80,14 +80,14 @@ function IssueBoard() {
|
|||
});
|
||||
|
||||
const openIssue = (issueId: number) => {
|
||||
navigate({
|
||||
void navigate({
|
||||
to: Route.fullPath,
|
||||
search: (prev) => normalizeIssuesSearch({ ...prev, issueId }),
|
||||
});
|
||||
};
|
||||
|
||||
const onCategoryChange = (category: string) => {
|
||||
navigate({
|
||||
void navigate({
|
||||
to: Route.fullPath,
|
||||
search: (prev) =>
|
||||
normalizeIssuesSearch({
|
||||
|
|
@ -99,7 +99,7 @@ function IssueBoard() {
|
|||
};
|
||||
|
||||
const onStatusChange = (status: IssueStatus | 'all') => {
|
||||
navigate({
|
||||
void navigate({
|
||||
to: Route.fullPath,
|
||||
search: (prev) =>
|
||||
normalizeIssuesSearch({
|
||||
|
|
|
|||
Loading…
Reference in a new issue