Refine issue detail modal rendering
- use a scoped renderer for the loading, error, and success lifecycle - keep Show for the larger conditional blocks inside the success view - simplify small pending-label branches back to plain ternaries
This commit is contained in:
parent
6471b291fa
commit
892334007d
1 changed files with 231 additions and 205 deletions
|
|
@ -3,6 +3,7 @@ import { useEffect, useMemo, useState, type ReactNode } from 'react';
|
||||||
|
|
||||||
import { DialogBody, DialogFooter, DialogFrame, DialogHeader } from '@/components/dialog';
|
import { DialogBody, DialogFooter, DialogFrame, DialogHeader } from '@/components/dialog';
|
||||||
import { Button } from '@/components/form';
|
import { Button } from '@/components/form';
|
||||||
|
import { Show } from '@/components/primitives';
|
||||||
import { useProfile } from '@/platform/shell/route-controllers';
|
import { useProfile } from '@/platform/shell/route-controllers';
|
||||||
import {
|
import {
|
||||||
launchAlbumDownloadWorkflow,
|
launchAlbumDownloadWorkflow,
|
||||||
|
|
@ -210,207 +211,7 @@ export function IssueDetailModal({
|
||||||
title={issue ? `Issue #${issue.id}` : 'Issue details'}
|
title={issue ? `Issue #${issue.id}` : 'Issue details'}
|
||||||
closeLabel="Close issue detail"
|
closeLabel="Close issue detail"
|
||||||
/>
|
/>
|
||||||
<DialogBody>
|
<DialogBody>{renderIssueDetailContent()}</DialogBody>
|
||||||
{queryLoading ? (
|
|
||||||
<div className={styles.issuesLoading}>
|
|
||||||
<div className={styles.issuesSpinner} />
|
|
||||||
Loading issue details...
|
|
||||||
</div>
|
|
||||||
) : queryError ? (
|
|
||||||
<div className={styles.issuesEmpty}>
|
|
||||||
<div className={styles.issuesEmptyTitle}>Failed to load issue</div>
|
|
||||||
<div className={styles.issuesEmptyText}>
|
|
||||||
{queryError instanceof Error ? queryError.message : 'Unknown error'}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : issue ? (
|
|
||||||
<>
|
|
||||||
<div className={styles.issueHero}>
|
|
||||||
<div className={styles.issueHeroArtGroup}>
|
|
||||||
{issue.entity_type === 'artist' && issueArtwork ? (
|
|
||||||
<img className={styles.issueHeroArtistThumb} src={issueArtwork} alt="" />
|
|
||||||
) : null}
|
|
||||||
{issueArtwork ? (
|
|
||||||
<img className={styles.issueHeroAlbumArt} src={issueArtwork} alt="" />
|
|
||||||
) : (
|
|
||||||
<div className={styles.issueHeroAlbumPlaceholder}>
|
|
||||||
{issueCategoryMeta?.icon || ISSUE_CATEGORY_META.other.icon}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className={styles.issueHeroInfo}>
|
|
||||||
{issue.entity_type !== 'artist' && snapshot.artist_name ? (
|
|
||||||
<div className={styles.issueHeroArtist}>{String(snapshot.artist_name)}</div>
|
|
||||||
) : null}
|
|
||||||
<div className={styles.issueHeroAlbum}>
|
|
||||||
{String(
|
|
||||||
issue.entity_type === 'artist'
|
|
||||||
? snapshot.name || issue.title
|
|
||||||
: snapshot.album_title || snapshot.title || issue.title,
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{issue.entity_type === 'track' ? (
|
|
||||||
<div className={styles.issueHeroTrackName}>♪ {issue.title}</div>
|
|
||||||
) : null}
|
|
||||||
{issue.entity_type !== 'artist' && albumMetaParts.length > 0 ? (
|
|
||||||
<div className={styles.issueHeroMeta}>{albumMetaParts.join(' - ')}</div>
|
|
||||||
) : null}
|
|
||||||
{genreTags.length > 0 ? (
|
|
||||||
<div className={styles.issueHeroGenres}>
|
|
||||||
{genreTags.map((genre) => (
|
|
||||||
<span className={styles.issueHeroGenreTag} key={String(genre)}>
|
|
||||||
{String(genre)}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
{externalLinks.length > 0 ? (
|
|
||||||
<div className={styles.issueExternalLinks}>
|
|
||||||
{externalLinks.map((link) =>
|
|
||||||
link.url ? (
|
|
||||||
<a
|
|
||||||
key={`${link.service}-${link.type}-${link.label}`}
|
|
||||||
className={`${styles.issueExternalLink} ${styles[link.className]}`}
|
|
||||||
href={link.url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
title={`${link.service} ${link.type}`}
|
|
||||||
>
|
|
||||||
<span className={styles.issueExternalLinkService}>{link.service}</span>
|
|
||||||
<span className={styles.issueExternalLinkType}>{link.type}</span>
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
<span
|
|
||||||
key={`${link.service}-${link.type}-${link.label}`}
|
|
||||||
className={`${styles.issueExternalLink} ${styles[link.className]}`}
|
|
||||||
title={`${link.service} ${link.type}: ${link.id}`}
|
|
||||||
>
|
|
||||||
<span className={styles.issueExternalLinkService}>{link.service}</span>
|
|
||||||
<span className={styles.issueExternalLinkType}>{link.type}</span>
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.issueDetailInfoBar}>
|
|
||||||
<div className={styles.issueDetailInfoLeft}>
|
|
||||||
<span
|
|
||||||
className={`${styles.issuePriorityDot} ${getPriorityDotClassName(priorityLevel)}`}
|
|
||||||
/>
|
|
||||||
<span className={`${styles.issueStatusBadge} ${getStatusClassName(issue.status)}`}>
|
|
||||||
{formatStatusLabel(issue.status)}
|
|
||||||
</span>
|
|
||||||
<span className={styles.issueDetailCategory}>{issueCategoryLabel}</span>
|
|
||||||
</div>
|
|
||||||
<div className={styles.issueDetailInfoRight}>
|
|
||||||
<span className={styles.issueDetailDate}>
|
|
||||||
Reported {formatIssueDate(issue.created_at)}
|
|
||||||
</span>
|
|
||||||
{issue.resolved_at ? (
|
|
||||||
<span className={styles.issueDetailDate}>
|
|
||||||
Resolved {formatIssueDate(issue.resolved_at)}
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
{issue.reporter_name && isAdmin ? (
|
|
||||||
<span className={styles.issueDetailProfile}>by {issue.reporter_name}</span>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{issue.entity_type !== 'artist' && isAdmin && (
|
|
||||||
<div className={styles.issueDetailSection}>
|
|
||||||
<div className={styles.issueDetailSectionTitle}>Admin Actions</div>
|
|
||||||
<div className={styles.issueActionButtons}>
|
|
||||||
<Button
|
|
||||||
className={styles.issueActionDownload}
|
|
||||||
type="button"
|
|
||||||
disabled={downloadWorkflowMutation.isPending}
|
|
||||||
onClick={() => downloadWorkflowMutation.mutate(albumWorkflowInput)}
|
|
||||||
>
|
|
||||||
{downloadWorkflowMutation.isPending ? 'Loading...' : 'Download Album'}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
className={styles.issueActionWishlist}
|
|
||||||
type="button"
|
|
||||||
disabled={wishlistWorkflowMutation.isPending}
|
|
||||||
onClick={() => wishlistWorkflowMutation.mutate(albumWorkflowInput)}
|
|
||||||
>
|
|
||||||
{wishlistWorkflowMutation.isPending ? 'Loading...' : 'Add to Wishlist'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className={styles.issueDetailSection}>
|
|
||||||
<div className={styles.issueDetailSectionTitle}>Issue</div>
|
|
||||||
<div className={styles.issueDetailTitleText}>{issue.title}</div>
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
issue.description ? styles.issueDetailDescription : styles.issueDetailNoDesc
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{issue.description || 'No additional details provided'}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{issue.entity_type === 'track' && trackMetaItems.length > 0 ? (
|
|
||||||
<div className={styles.issueDetailSection}>
|
|
||||||
<div className={styles.issueDetailSectionTitle}>Track Details</div>
|
|
||||||
<div className={styles.issueDetailMetaGrid}>
|
|
||||||
{trackMetaItems.map((item) => (
|
|
||||||
<div className={styles.issueMetaItem} key={item.label}>
|
|
||||||
<span className={styles.issueMetaIcon}>{item.icon}</span>
|
|
||||||
<span className={styles.issueMetaLabel}>{item.label}</span>
|
|
||||||
<span className={styles.issueMetaValue}>{item.value}</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{snapshot.file_path ? (
|
|
||||||
<div className={styles.issueDetailSection}>
|
|
||||||
<div className={styles.issueDetailSectionTitle}>File Path</div>
|
|
||||||
<div className={styles.issueDetailFilepath}>{String(snapshot.file_path)}</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{trackRows.length > 0 ? (
|
|
||||||
<div className={styles.issueDetailSection}>
|
|
||||||
<div className={styles.issueDetailSectionTitle}>
|
|
||||||
Track Listing{' '}
|
|
||||||
<span className={styles.issueDetailSectionCount}>{trackRows.length} tracks</span>
|
|
||||||
</div>
|
|
||||||
<div className={styles.issueDetailTracklist}>{renderTrackListing(trackRows)}</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{isAdmin && (
|
|
||||||
<div className={styles.issueDetailSection}>
|
|
||||||
<div className={styles.issueDetailSectionTitle}>Admin Response</div>
|
|
||||||
<textarea
|
|
||||||
className={styles.issueDetailResponseTextarea}
|
|
||||||
id="issue-detail-response-input"
|
|
||||||
value={adminResponse}
|
|
||||||
onChange={(event) => setAdminResponse(event.target.value)}
|
|
||||||
placeholder="Write a response to the reporter..."
|
|
||||||
rows={3}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isAdmin && issue.admin_response ? (
|
|
||||||
<div className={styles.issueDetailSection}>
|
|
||||||
<div className={styles.issueDetailSectionTitle}>Admin Response</div>
|
|
||||||
<div className={styles.issueDetailAdminResponse}>{issue.admin_response}</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</DialogBody>
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button className={styles.modalButtonSecondary} type="button" onClick={onClose}>
|
<Button className={styles.modalButtonSecondary} type="button" onClick={onClose}>
|
||||||
Close
|
Close
|
||||||
|
|
@ -437,6 +238,231 @@ export function IssueDetailModal({
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogFrame>
|
</DialogFrame>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function renderIssueDetailContent() {
|
||||||
|
if (queryLoading) {
|
||||||
|
return (
|
||||||
|
<div className={styles.issuesLoading}>
|
||||||
|
<div className={styles.issuesSpinner} />
|
||||||
|
Loading issue details...
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queryError) {
|
||||||
|
return (
|
||||||
|
<div className={styles.issuesEmpty}>
|
||||||
|
<div className={styles.issuesEmptyTitle}>Failed to load issue</div>
|
||||||
|
<div className={styles.issuesEmptyText}>
|
||||||
|
{queryError instanceof Error ? queryError.message : 'Unknown error'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!issue) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={styles.issueHero}>
|
||||||
|
<div className={styles.issueHeroArtGroup}>
|
||||||
|
<Show when={issue.entity_type === 'artist' && issueArtwork}>
|
||||||
|
<img className={styles.issueHeroArtistThumb} src={issueArtwork} alt="" />
|
||||||
|
</Show>
|
||||||
|
<Show
|
||||||
|
when={issueArtwork}
|
||||||
|
fallback={
|
||||||
|
<div className={styles.issueHeroAlbumPlaceholder}>
|
||||||
|
{issueCategoryMeta?.icon || ISSUE_CATEGORY_META.other.icon}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<img className={styles.issueHeroAlbumArt} src={issueArtwork} alt="" />
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
<div className={styles.issueHeroInfo}>
|
||||||
|
<Show when={issue.entity_type !== 'artist' && snapshot.artist_name}>
|
||||||
|
{(artistName) => <div className={styles.issueHeroArtist}>{String(artistName)}</div>}
|
||||||
|
</Show>
|
||||||
|
<div className={styles.issueHeroAlbum}>
|
||||||
|
{String(
|
||||||
|
issue.entity_type === 'artist'
|
||||||
|
? snapshot.name || issue.title
|
||||||
|
: snapshot.album_title || snapshot.title || issue.title,
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<Show when={issue.entity_type === 'track'}>
|
||||||
|
<div className={styles.issueHeroTrackName}>♪ {issue.title}</div>
|
||||||
|
</Show>
|
||||||
|
<Show when={issue.entity_type !== 'artist' && albumMetaParts.length > 0}>
|
||||||
|
<div className={styles.issueHeroMeta}>{albumMetaParts.join(' - ')}</div>
|
||||||
|
</Show>
|
||||||
|
<Show when={genreTags.length}>
|
||||||
|
<div className={styles.issueHeroGenres}>
|
||||||
|
{genreTags.map((genre) => (
|
||||||
|
<span className={styles.issueHeroGenreTag} key={String(genre)}>
|
||||||
|
{String(genre)}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
<Show when={externalLinks.length}>
|
||||||
|
<div className={styles.issueExternalLinks}>
|
||||||
|
{externalLinks.map((link) => (
|
||||||
|
<Show
|
||||||
|
key={`${link.service}-${link.type}-${link.label}`}
|
||||||
|
when={link.url}
|
||||||
|
fallback={
|
||||||
|
<span
|
||||||
|
className={`${styles.issueExternalLink} ${styles[link.className]}`}
|
||||||
|
title={`${link.service} ${link.type}: ${link.id}`}
|
||||||
|
>
|
||||||
|
<span className={styles.issueExternalLinkService}>{link.service}</span>
|
||||||
|
<span className={styles.issueExternalLinkType}>{link.type}</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className={`${styles.issueExternalLink} ${styles[link.className]}`}
|
||||||
|
href={link.url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
title={`${link.service} ${link.type}`}
|
||||||
|
>
|
||||||
|
<span className={styles.issueExternalLinkService}>{link.service}</span>
|
||||||
|
<span className={styles.issueExternalLinkType}>{link.type}</span>
|
||||||
|
</a>
|
||||||
|
</Show>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.issueDetailInfoBar}>
|
||||||
|
<div className={styles.issueDetailInfoLeft}>
|
||||||
|
<span
|
||||||
|
className={`${styles.issuePriorityDot} ${getPriorityDotClassName(priorityLevel)}`}
|
||||||
|
/>
|
||||||
|
<span className={`${styles.issueStatusBadge} ${getStatusClassName(issue.status)}`}>
|
||||||
|
{formatStatusLabel(issue.status)}
|
||||||
|
</span>
|
||||||
|
<span className={styles.issueDetailCategory}>{issueCategoryLabel}</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.issueDetailInfoRight}>
|
||||||
|
<span className={styles.issueDetailDate}>
|
||||||
|
Reported {formatIssueDate(issue.created_at)}
|
||||||
|
</span>
|
||||||
|
<Show when={issue.resolved_at}>
|
||||||
|
{(resolvedAt) => (
|
||||||
|
<span className={styles.issueDetailDate}>
|
||||||
|
Resolved {formatIssueDate(resolvedAt)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Show>
|
||||||
|
<Show when={isAdmin && issue.reporter_name}>
|
||||||
|
{(reporterName) => (
|
||||||
|
<span className={styles.issueDetailProfile}>by {reporterName}</span>
|
||||||
|
)}
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Show when={issue.entity_type !== 'artist' && isAdmin}>
|
||||||
|
<div className={styles.issueDetailSection}>
|
||||||
|
<div className={styles.issueDetailSectionTitle}>Admin Actions</div>
|
||||||
|
<div className={styles.issueActionButtons}>
|
||||||
|
<Button
|
||||||
|
className={styles.issueActionDownload}
|
||||||
|
type="button"
|
||||||
|
disabled={downloadWorkflowMutation.isPending}
|
||||||
|
onClick={() => downloadWorkflowMutation.mutate(albumWorkflowInput)}
|
||||||
|
>
|
||||||
|
{downloadWorkflowMutation.isPending ? 'Loading...' : 'Download Album'}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className={styles.issueActionWishlist}
|
||||||
|
type="button"
|
||||||
|
disabled={wishlistWorkflowMutation.isPending}
|
||||||
|
onClick={() => wishlistWorkflowMutation.mutate(albumWorkflowInput)}
|
||||||
|
>
|
||||||
|
{wishlistWorkflowMutation.isPending ? 'Loading...' : 'Add to Wishlist'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<div className={styles.issueDetailSection}>
|
||||||
|
<div className={styles.issueDetailSectionTitle}>Issue</div>
|
||||||
|
<div className={styles.issueDetailTitleText}>{issue.title}</div>
|
||||||
|
<div
|
||||||
|
className={issue.description ? styles.issueDetailDescription : styles.issueDetailNoDesc}
|
||||||
|
>
|
||||||
|
{issue.description || 'No additional details provided'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Show when={issue.entity_type === 'track' && trackMetaItems.length > 0}>
|
||||||
|
<div className={styles.issueDetailSection}>
|
||||||
|
<div className={styles.issueDetailSectionTitle}>Track Details</div>
|
||||||
|
<div className={styles.issueDetailMetaGrid}>
|
||||||
|
{trackMetaItems.map((item) => (
|
||||||
|
<div className={styles.issueMetaItem} key={item.label}>
|
||||||
|
<span className={styles.issueMetaIcon}>{item.icon}</span>
|
||||||
|
<span className={styles.issueMetaLabel}>{item.label}</span>
|
||||||
|
<span className={styles.issueMetaValue}>{item.value}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={snapshot.file_path}>
|
||||||
|
{(filePath) => (
|
||||||
|
<div className={styles.issueDetailSection}>
|
||||||
|
<div className={styles.issueDetailSectionTitle}>File Path</div>
|
||||||
|
<div className={styles.issueDetailFilepath}>{String(filePath)}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={trackRows.length}>
|
||||||
|
<div className={styles.issueDetailSection}>
|
||||||
|
<div className={styles.issueDetailSectionTitle}>
|
||||||
|
Track Listing{' '}
|
||||||
|
<span className={styles.issueDetailSectionCount}>{trackRows.length} tracks</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.issueDetailTracklist}>{renderTrackListing(trackRows)}</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={isAdmin}>
|
||||||
|
<div className={styles.issueDetailSection}>
|
||||||
|
<div className={styles.issueDetailSectionTitle}>Admin Response</div>
|
||||||
|
<textarea
|
||||||
|
className={styles.issueDetailResponseTextarea}
|
||||||
|
id="issue-detail-response-input"
|
||||||
|
value={adminResponse}
|
||||||
|
onChange={(event) => setAdminResponse(event.target.value)}
|
||||||
|
placeholder="Write a response to the reporter..."
|
||||||
|
rows={3}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={!isAdmin && issue.admin_response}>
|
||||||
|
{(response) => (
|
||||||
|
<div className={styles.issueDetailSection}>
|
||||||
|
<div className={styles.issueDetailSectionTitle}>Admin Response</div>
|
||||||
|
<div className={styles.issueDetailAdminResponse}>{response}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Show>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTrackListing(trackRows: IssueTrackRow[]) {
|
function renderTrackListing(trackRows: IssueTrackRow[]) {
|
||||||
|
|
@ -470,12 +496,12 @@ function renderTrackListing(trackRows: IssueTrackRow[]) {
|
||||||
<span className={styles.issueDetailTracklistTitle}>{String(track.title || 'Unknown')}</span>
|
<span className={styles.issueDetailTracklistTitle}>{String(track.title || 'Unknown')}</span>
|
||||||
<span className={styles.issueDetailTracklistDur}>{duration}</span>
|
<span className={styles.issueDetailTracklistDur}>{duration}</span>
|
||||||
<span className={styles.issueDetailTracklistMeta}>
|
<span className={styles.issueDetailTracklistMeta}>
|
||||||
{format ? (
|
<Show when={format}>
|
||||||
<span className={`${styles.issueTrackBadge} ${formatClassName}`}>{format}</span>
|
<span className={`${styles.issueTrackBadge} ${formatClassName}`}>{format}</span>
|
||||||
) : null}
|
</Show>
|
||||||
{bitrate ? (
|
<Show when={bitrate}>
|
||||||
<span className={`${styles.issueTrackBadge} ${bitrateClassName}`}>{bitrate}</span>
|
<span className={`${styles.issueTrackBadge} ${bitrateClassName}`}>{bitrate}</span>
|
||||||
) : null}
|
</Show>
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue