refactor(import): normalize controls and classes
- let the singles action buttons use the default size again - remove redundant type="button" props from import controls - switch import page conditional classes to clsx object notation - drop route-test assertions that pinned compact auto-import sizes
This commit is contained in:
parent
9ba54bd82d
commit
7a0548ac94
5 changed files with 70 additions and 117 deletions
|
|
@ -304,13 +304,6 @@ describe('import route', () => {
|
|||
expect(await screen.findByRole('button', { name: /^Needs Review\s*1$/ })).toBeInTheDocument();
|
||||
expect(screen.getAllByText('Album A').length).toBeGreaterThan(0);
|
||||
expect(screen.getByText('Watching')).toHaveAttribute('data-tone', 'success');
|
||||
const compactFilterGroup = document.querySelector('#auto-import-results [data-size="sm"]');
|
||||
expect(compactFilterGroup).toBeInTheDocument();
|
||||
const intervalSelect = document.getElementById('auto-import-interval');
|
||||
if (!(intervalSelect instanceof HTMLElement)) {
|
||||
throw new Error('auto-import interval select missing');
|
||||
}
|
||||
expect(intervalSelect).toHaveAttribute('data-size', 'sm');
|
||||
expect(getFetchUrls().some((url) => url.includes('/api/import/staging/groups'))).toBe(false);
|
||||
expect(getFetchUrls().some((url) => url.includes('/api/import/staging/suggestions'))).toBe(
|
||||
false,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
import { type DragEvent, type KeyboardEvent, useState } from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { Button, TextInput } from '@/components/form/form';
|
||||
|
||||
import type { ImportAlbumResult } from '../-import.types';
|
||||
import styles from './import-page.module.css';
|
||||
|
||||
import {
|
||||
importStagingGroupsQueryOptions,
|
||||
|
|
@ -20,6 +20,7 @@ import {
|
|||
IMPORT_PLACEHOLDER_IMAGE,
|
||||
} from '../-import.helpers';
|
||||
import { useAlbumImportWorkflow } from '../-import.store';
|
||||
import styles from './import-page.module.css';
|
||||
import {
|
||||
fallbackImage,
|
||||
getErrorMessage,
|
||||
|
|
@ -235,10 +236,7 @@ function AlbumImportPanelContent({ viewModel }: { viewModel: AlbumImportViewMode
|
|||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
id="import-page-album-search-section"
|
||||
className={showingMatch ? styles.hidden : ''}
|
||||
>
|
||||
<div id="import-page-album-search-section" className={clsx({ [styles.hidden]: showingMatch })}>
|
||||
{albumResults === null && (
|
||||
<>
|
||||
{groups.length > 0 && (
|
||||
|
|
@ -246,10 +244,9 @@ function AlbumImportPanelContent({ viewModel }: { viewModel: AlbumImportViewMode
|
|||
<div className={styles.importPageSectionLabel}>Auto-Detected Albums</div>
|
||||
<div className={styles.importPageAlbumGrid}>
|
||||
{groups.map((group, index) => (
|
||||
<button
|
||||
<button
|
||||
key={`${group.artist}-${group.album}-${index}`}
|
||||
type="button"
|
||||
className={`${styles.importPageAlbumCard} ${styles.importPageAutoGroupCard}`}
|
||||
className={clsx(styles.importPageAlbumCard, styles.importPageAutoGroupCard)}
|
||||
onClick={() => onRunGroupSearch(group)}
|
||||
>
|
||||
<div className={styles.importPageAutoGroupCount}>{group.file_count}</div>
|
||||
|
|
@ -299,17 +296,16 @@ function AlbumImportPanelContent({ viewModel }: { viewModel: AlbumImportViewMode
|
|||
}}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={albumResults === null ? styles.hidden : ''}
|
||||
className={clsx({ [styles.hidden]: albumResults === null })}
|
||||
id="import-page-album-clear-btn"
|
||||
title="Clear search"
|
||||
onClick={onBackToSearch}
|
||||
>
|
||||
x
|
||||
</Button>
|
||||
<Button type="button" variant="primary" onClick={onRunSearch}>
|
||||
<Button variant="primary" onClick={onRunSearch}>
|
||||
Search
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -333,10 +329,7 @@ function AlbumImportPanelContent({ viewModel }: { viewModel: AlbumImportViewMode
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="import-page-album-match-section"
|
||||
className={showingMatch ? '' : styles.hidden}
|
||||
>
|
||||
<div id="import-page-album-match-section" className={clsx({ [styles.hidden]: !showingMatch })}>
|
||||
{albumMatchLoading ? (
|
||||
<div className={styles.importPageEmptyState}>Matching files to tracklist...</div>
|
||||
) : albumMatchError ? (
|
||||
|
|
@ -344,7 +337,9 @@ function AlbumImportPanelContent({ viewModel }: { viewModel: AlbumImportViewMode
|
|||
) : albumMatch?.album ? (
|
||||
<AlbumMatchPanel viewModel={viewModel} />
|
||||
) : (
|
||||
<div className={styles.importPageEmptyState}>Select an album to start matching files.</div>
|
||||
<div className={styles.importPageEmptyState}>
|
||||
Select an album to start matching files.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
|
@ -359,7 +354,7 @@ function AlbumCard({
|
|||
onSelect: (album: ImportAlbumResult) => void;
|
||||
}) {
|
||||
return (
|
||||
<button type="button" className={styles.importPageAlbumCard} onClick={() => onSelect(album)}>
|
||||
<button className={styles.importPageAlbumCard} onClick={() => onSelect(album)}>
|
||||
<img
|
||||
src={album.image_url || IMPORT_PLACEHOLDER_IMAGE}
|
||||
alt={album.name}
|
||||
|
|
@ -435,20 +430,10 @@ function AlbumMatchPanel({ viewModel }: { viewModel: AlbumImportViewModel }) {
|
|||
<div className={styles.importPageMatchHeader}>
|
||||
<h3>Track Matching</h3>
|
||||
<div className={styles.importPageMatchActions}>
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={onAutoRematch}
|
||||
>
|
||||
<Button variant="secondary" onClick={onAutoRematch}>
|
||||
Re-match Automatically
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onBackToSearch}
|
||||
>
|
||||
<Button variant="ghost" onClick={onBackToSearch}>
|
||||
Back to Search
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -467,9 +452,10 @@ function AlbumMatchPanel({ viewModel }: { viewModel: AlbumImportViewModel }) {
|
|||
return (
|
||||
<div
|
||||
key={`${trackInfo.displayTrackNumber}-${trackInfo.name}-${index}`}
|
||||
className={`${styles.importPageMatchRow} ${
|
||||
file ? styles.matched : ''
|
||||
} ${dragOverTrack === index ? styles.dragOver : ''}`}
|
||||
className={clsx(styles.importPageMatchRow, {
|
||||
[styles.matched]: file,
|
||||
[styles.dragOver]: dragOverTrack === index,
|
||||
})}
|
||||
onClick={() => {
|
||||
if (tapSelectedChip !== null) onTapAssign(index, tapSelectedChip);
|
||||
}}
|
||||
|
|
@ -488,18 +474,16 @@ function AlbumMatchPanel({ viewModel }: { viewModel: AlbumImportViewModel }) {
|
|||
>
|
||||
<span className={styles.importPageMatchNum}>{trackInfo.displayTrackNumber}</span>
|
||||
<span className={styles.importPageMatchTrack}>{trackInfo.name}</span>
|
||||
<span
|
||||
className={`${styles.importPageMatchFile} ${
|
||||
file ? styles.hasFile : ''
|
||||
}`}
|
||||
>
|
||||
<span className={clsx(styles.importPageMatchFile, {
|
||||
[styles.hasFile]: file,
|
||||
})}>
|
||||
{file ? (
|
||||
<>
|
||||
<span className={styles.importPageMatchFileName}>{file.filename}</span>
|
||||
<span
|
||||
className={`${styles.importPageMatchConfidence} ${
|
||||
confidence >= 0.7 ? '' : styles.low
|
||||
}`}
|
||||
className={clsx(styles.importPageMatchConfidence, {
|
||||
[styles.low]: confidence < 0.7,
|
||||
})}
|
||||
>
|
||||
{confidencePercent}%
|
||||
</span>
|
||||
|
|
@ -511,7 +495,6 @@ function AlbumMatchPanel({ viewModel }: { viewModel: AlbumImportViewModel }) {
|
|||
<span>
|
||||
{file ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={(event) => {
|
||||
|
|
@ -541,9 +524,9 @@ function AlbumMatchPanel({ viewModel }: { viewModel: AlbumImportViewModel }) {
|
|||
key={`${file.full_path}-${index}`}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className={`${styles.importPageFileChip} ${
|
||||
tapSelectedChip === index ? styles.selected : ''
|
||||
}`}
|
||||
className={clsx(styles.importPageFileChip, {
|
||||
[styles.selected]: tapSelectedChip === index,
|
||||
})}
|
||||
draggable
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
|
|
@ -572,7 +555,6 @@ function AlbumMatchPanel({ viewModel }: { viewModel: AlbumImportViewModel }) {
|
|||
{matchedCount} of {albumMatch.matches?.length ?? 0} tracks matched
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="primary"
|
||||
id="import-page-album-process-btn"
|
||||
disabled={matchedCount === 0}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import clsx from 'clsx';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
|
|
@ -179,9 +180,7 @@ export function AutoImportPanel({
|
|||
<div className={styles.importPageFlexSpacer} />
|
||||
{statusQuery.data?.running ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
id="auto-import-scan-now"
|
||||
title="Scan import folder now"
|
||||
disabled={scanMutation.isPending}
|
||||
|
|
@ -222,7 +221,6 @@ export function AutoImportPanel({
|
|||
</Select>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
disabled={saveSettingsMutation.isPending}
|
||||
|
|
@ -271,9 +269,7 @@ export function AutoImportPanel({
|
|||
<div className={styles.importPageFlexSpacer} />
|
||||
{counts.review > 0 ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
id="auto-import-approve-all"
|
||||
disabled={approveAllMutation.isPending}
|
||||
onClick={() => approveAllMutation.mutate()}
|
||||
|
|
@ -283,11 +279,10 @@ export function AutoImportPanel({
|
|||
) : null}
|
||||
{counts.imported + counts.failed > 0 ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
id="auto-import-clear-completed"
|
||||
disabled={clearMutation.isPending}
|
||||
size="sm"
|
||||
onClick={() => clearMutation.mutate()}
|
||||
>
|
||||
Clear History
|
||||
|
|
@ -389,7 +384,7 @@ function AutoImportResultCard({
|
|||
|
||||
return (
|
||||
<div
|
||||
className={`${styles.autoImportCard} ${statusCardClass}`}
|
||||
className={clsx(styles.autoImportCard, statusCardClass)}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={onToggle}
|
||||
|
|
@ -432,12 +427,12 @@ function AutoImportResultCard({
|
|||
) : null}
|
||||
</div>
|
||||
<div className={styles.autoImportCardRight}>
|
||||
<div className={`${styles.autoImportStatusBadge} ${statusBadgeClass}`}>
|
||||
<div className={clsx(styles.autoImportStatusBadge, statusBadgeClass)}>
|
||||
{statusMeta.icon} {statusMeta.label}
|
||||
</div>
|
||||
<div className={styles.autoImportConfidenceBar}>
|
||||
<div
|
||||
className={`${styles.autoImportConfidenceFill} ${confidenceFillClass}`}
|
||||
className={clsx(styles.autoImportConfidenceFill, confidenceFillClass)}
|
||||
style={{ width: `${confidencePercent}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -445,9 +440,7 @@ function AutoImportResultCard({
|
|||
{result.status === 'pending_review' ? (
|
||||
<div className={styles.autoImportActions}>
|
||||
<Button
|
||||
type="button"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
disabled={approvePending}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
|
|
@ -457,9 +450,7 @@ function AutoImportResultCard({
|
|||
Approve & Import
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
disabled={rejectPending}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
|
|
@ -475,7 +466,9 @@ function AutoImportResultCard({
|
|||
<div className={styles.autoImportCardFolderPath}>{result.folder_name}</div>
|
||||
{trackDetails.length > 0 ? (
|
||||
<div
|
||||
className={`${styles.autoImportTrackList} ${expanded ? styles.expanded : ''}`}
|
||||
className={clsx(styles.autoImportTrackList, {
|
||||
[styles.expanded]: expanded,
|
||||
})}
|
||||
id={`auto-import-tracks-${index}`}
|
||||
>
|
||||
<div className={styles.autoImportTrackListHeader}>
|
||||
|
|
@ -484,23 +477,21 @@ function AutoImportResultCard({
|
|||
<span>Conf</span>
|
||||
</div>
|
||||
{trackDetails.map((track, trackIndex) => {
|
||||
const rowClassName = [
|
||||
styles.autoImportTrackRow,
|
||||
isLiveProcessing && liveTrackIndex > 0 && trackIndex + 1 === liveTrackIndex
|
||||
? styles.autoImportTrackRowActive
|
||||
: '',
|
||||
isLiveProcessing && liveTrackIndex > 0 && trackIndex + 1 < liveTrackIndex
|
||||
? styles.autoImportTrackRowDone
|
||||
: '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ');
|
||||
const rowClassName = clsx(styles.autoImportTrackRow, {
|
||||
[styles.autoImportTrackRowActive]:
|
||||
isLiveProcessing && liveTrackIndex > 0 && trackIndex + 1 === liveTrackIndex,
|
||||
[styles.autoImportTrackRowDone]:
|
||||
isLiveProcessing && liveTrackIndex > 0 && trackIndex + 1 < liveTrackIndex,
|
||||
});
|
||||
return (
|
||||
<div key={`${track.name}-${track.file}-${trackIndex}`} className={rowClassName}>
|
||||
<span className={styles.autoImportTrackName}>{track.name}</span>
|
||||
<span className={styles.autoImportTrackFile}>{track.file}</span>
|
||||
<span
|
||||
className={`${styles.autoImportTrackConf} ${getAutoImportConfidenceClass(getConfidenceClass(track.confidence))}`}
|
||||
className={clsx(
|
||||
styles.autoImportTrackConf,
|
||||
getAutoImportConfidenceClass(getConfidenceClass(track.confidence)),
|
||||
)}
|
||||
>
|
||||
{track.confidence}%
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { Link, Outlet } from '@tanstack/react-router';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { Show } from '@/components/primitives';
|
||||
import { Button } from '@/components/form/form';
|
||||
import { Show } from '@/components/primitives';
|
||||
import { useReactPageShell } from '@/platform/shell/route-controllers';
|
||||
|
||||
import type { ImportQueueEntry } from '../-import.types';
|
||||
|
|
@ -37,7 +38,7 @@ export function ImportPage() {
|
|||
/>
|
||||
<ImportProcessingQueue />
|
||||
<ImportTabNav />
|
||||
<section className={`${styles.importPageTabContent} ${styles.active}`}>
|
||||
<section className={clsx(styles.importPageTabContent, styles.active)}>
|
||||
<Outlet />
|
||||
</section>
|
||||
</div>
|
||||
|
|
@ -78,7 +79,6 @@ function ImportHeader({
|
|||
<span>Import Music</span>
|
||||
</h1>
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
title="Re-scan import folder"
|
||||
aria-busy={refreshing}
|
||||
|
|
@ -112,15 +112,15 @@ function ImportProcessingQueue() {
|
|||
|
||||
return (
|
||||
<section
|
||||
className={`${styles.importPageQueue} ${queue.length === 0 ? styles.hidden : ''}`}
|
||||
className={clsx(styles.importPageQueue, {
|
||||
[styles.hidden]: queue.length === 0,
|
||||
})}
|
||||
id="import-page-queue"
|
||||
>
|
||||
<div className={styles.importPageQueueHeader}>
|
||||
<span className={styles.importPageQueueTitle}>Processing</span>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
id="import-page-queue-clear"
|
||||
style={{ display: hasFinished ? undefined : 'none' }}
|
||||
onClick={clearFinishedJobs}
|
||||
|
|
@ -139,12 +139,10 @@ function ImportProcessingQueue() {
|
|||
|
||||
function ImportQueueItem({ entry }: { entry: ImportQueueEntry }) {
|
||||
const statusText = getQueueStatusText(entry);
|
||||
const statusClass =
|
||||
entry.status === 'error' || (entry.status === 'done' && entry.errors.length > 0)
|
||||
? styles.error
|
||||
: entry.status === 'done'
|
||||
? styles.done
|
||||
: '';
|
||||
const statusClass = clsx({
|
||||
[styles.error]: entry.status === 'error' || (entry.status === 'done' && entry.errors.length > 0),
|
||||
[styles.done]: entry.status === 'done',
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={styles.importPageQueueItem}>
|
||||
|
|
@ -156,7 +154,7 @@ function ImportQueueItem({ entry }: { entry: ImportQueueEntry }) {
|
|||
onError={fallbackImage}
|
||||
/>
|
||||
) : (
|
||||
<div className={`${styles.importPageQueueArt} ${styles.importPageQueueArtEmpty}`}>♪</div>
|
||||
<div className={clsx(styles.importPageQueueArt, styles.importPageQueueArtEmpty)}>♪</div>
|
||||
)}
|
||||
<div className={styles.importPageQueueInfo}>
|
||||
<div className={styles.importPageQueueName}>{entry.label}</div>
|
||||
|
|
@ -165,13 +163,13 @@ function ImportQueueItem({ entry }: { entry: ImportQueueEntry }) {
|
|||
<div className={styles.importPageQueueProgress}>
|
||||
<div className={styles.importPageQueueBar}>
|
||||
<div
|
||||
className={`${styles.importPageQueueFill} ${
|
||||
entry.status === 'error' ? styles.error : ''
|
||||
}`}
|
||||
className={clsx(styles.importPageQueueFill, {
|
||||
[styles.error]: entry.status === 'error',
|
||||
})}
|
||||
style={{ width: `${getQueueProgressPercent(entry)}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className={`${styles.importPageQueueStatus} ${statusClass}`}>{statusText}</div>
|
||||
<div className={clsx(styles.importPageQueueStatus, statusClass)}>{statusText}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -183,7 +181,7 @@ function ImportTabNav() {
|
|||
<Link
|
||||
to="/import/auto"
|
||||
className={styles.importPageTab}
|
||||
activeProps={{ className: `${styles.importPageTab} ${styles.active}` }}
|
||||
activeProps={{ className: clsx(styles.importPageTab, styles.active) }}
|
||||
id="import-page-tab-auto"
|
||||
>
|
||||
Auto
|
||||
|
|
@ -191,7 +189,7 @@ function ImportTabNav() {
|
|||
<Link
|
||||
to="/import/album"
|
||||
className={styles.importPageTab}
|
||||
activeProps={{ className: `${styles.importPageTab} ${styles.active}` }}
|
||||
activeProps={{ className: clsx(styles.importPageTab, styles.active) }}
|
||||
id="import-page-tab-album"
|
||||
>
|
||||
Albums
|
||||
|
|
@ -199,7 +197,7 @@ function ImportTabNav() {
|
|||
<Link
|
||||
to="/import/singles"
|
||||
className={styles.importPageTab}
|
||||
activeProps={{ className: `${styles.importPageTab} ${styles.active}` }}
|
||||
activeProps={{ className: clsx(styles.importPageTab, styles.active) }}
|
||||
id="import-page-tab-singles"
|
||||
>
|
||||
Singles
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import clsx from 'clsx';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { Badge, Button, Checkbox, TextInput } from '@/components/form/form';
|
||||
|
|
@ -175,17 +176,15 @@ export function SinglesImportPanel({
|
|||
<>
|
||||
<div className={styles.importPageSinglesHeader}>
|
||||
<div className={styles.importPageSinglesActions}>
|
||||
<Button type="button" variant="secondary" size="sm" onClick={onSelectAll}>
|
||||
<Button variant="secondary" onClick={onSelectAll}>
|
||||
<span id="import-page-select-all-text">
|
||||
{allSelected ? 'Deselect All' : 'Select All'}
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant={processVariant}
|
||||
id="import-page-singles-process-btn"
|
||||
disabled={selectedCount === 0}
|
||||
size="sm"
|
||||
onClick={onProcessSingles}
|
||||
>
|
||||
<span>Process Selected</span>
|
||||
|
|
@ -205,7 +204,9 @@ export function SinglesImportPanel({
|
|||
return (
|
||||
<div
|
||||
key={fileKey}
|
||||
className={`${styles.importPageSingleItem} ${manualMatch ? styles.matched : ''}`}
|
||||
className={clsx(styles.importPageSingleItem, {
|
||||
[styles.matched]: manualMatch,
|
||||
})}
|
||||
data-single-key={fileKey}
|
||||
>
|
||||
<label className={styles.importPageSingleCheckboxWrap}>
|
||||
|
|
@ -226,7 +227,6 @@ export function SinglesImportPanel({
|
|||
<div className={styles.importPageSingleMatchedInfo}>
|
||||
✓ {manualMatch.name} - {manualMatch.artist}
|
||||
<button
|
||||
type="button"
|
||||
className={styles.importPageSingleMatchedChange}
|
||||
onClick={() => onOpenSearch(file)}
|
||||
>
|
||||
|
|
@ -236,12 +236,7 @@ export function SinglesImportPanel({
|
|||
) : null}
|
||||
</div>
|
||||
<div className={styles.importPageSingleActions}>
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
onClick={() => onOpenSearch(file)}
|
||||
>
|
||||
<Button variant="secondary" size="sm" onClick={() => onOpenSearch(file)}>
|
||||
🔍 Identify
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -291,12 +286,7 @@ function SingleSearchPanel({
|
|||
if (event.key === 'Enter') onRunSearch(fileKey, query);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => onRunSearch(fileKey, query)}
|
||||
>
|
||||
<Button variant="primary" onClick={() => onRunSearch(fileKey, query)}>
|
||||
Search
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -311,7 +301,6 @@ function SingleSearchPanel({
|
|||
searchState?.results.map((track, index) => (
|
||||
<button
|
||||
key={`${track.source || 'source'}-${track.id}-${index}`}
|
||||
type="button"
|
||||
className={styles.importPageSingleResultItem}
|
||||
onClick={() => onSelectMatch(fileKey, track)}
|
||||
>
|
||||
|
|
|
|||
Loading…
Reference in a new issue