fix: admin bugs from the audit: a playback-error delete no longer reports failure, a failed Overview load no longer reads as all-clear, and email settings can't be saved over with defaults (M503 #5604)
release / govulncheck (push) Successful in 16s
release / web (push) Successful in 1m31s
release / go (push) Successful in 1m49s
release / integration (push) Successful in 5m20s
release / Build signed APK (releases and dev) (push) Successful in 5m9s
release / android (push) Successful in 6m26s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 25s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 16s
release / web (push) Successful in 1m31s
release / go (push) Successful in 1m49s
release / integration (push) Successful in 5m20s
release / Build signed APK (releases and dev) (push) Successful in 5m9s
release / android (push) Successful in 6m26s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 25s
release / Verify release artifacts (tag releases only) (push) Skipped
- Playback errors: Delete file stops resolving the error row the track deletion already took with it (ON DELETE CASCADE), which 404'd into "Delete failed". - Overview: a queue that fails to load says so with Try again, and its tile shows a dash, not 0. Delete via Lidarr shows only for an album Lidarr holds while Lidarr is connected. An approve refreshes the Collection. - Quarantine: Delete via Lidarr is in the row menu, so a phone reaches it; "1 report", not "1 reports". - Duplicates: the Keep badge follows the copy picked. - Integrations: provider save failures and load errors are said, not swallowed or shown as "No providers registered"; the Lidarr test catches a failed call; SMTP fills once and Save stays off until it has loaded. Lidarr's blurb says what it is still used for. - Requests: release profiles point at Collection › Following. - Library: an empty library sends an admin to Admin to run a scan, and tells anyone else the admin scans it, instead of opening Settings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -432,7 +432,8 @@
|
||||
|
||||
<ul class="divide-y divide-border">
|
||||
{#each group.members as m (m.track_id)}
|
||||
{@const keep = m.track_id === group.survivor_track_id}
|
||||
{@const keep = keeperOf(group) === m.track_id}
|
||||
{@const proposed = m.track_id === group.survivor_track_id}
|
||||
<li class="flex items-start gap-3 px-4 py-3" data-testid="duplicate-member">
|
||||
<input
|
||||
type="radio"
|
||||
@@ -446,14 +447,15 @@
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<span class="truncate text-sm text-text-primary">{m.title}</span>
|
||||
{#if keep}
|
||||
<!-- The proposed copy to keep, with the rule that chose it.
|
||||
A default the merge will let the operator override. -->
|
||||
<!-- The copy the merge will keep: the proposed one with the
|
||||
rule that chose it, or the one the operator picked. The
|
||||
badge follows the pick, as the merge does (#5604). -->
|
||||
<span
|
||||
class="shrink-0 rounded-full bg-accent-tint px-2 py-0.5 text-xs text-accent-fg"
|
||||
data-testid="survivor-badge"
|
||||
title="Proposed to keep: {group.survivor_reason}"
|
||||
title={proposed ? `Proposed to keep: ${group.survivor_reason}` : 'Your pick'}
|
||||
>
|
||||
Keep · {group.survivor_reason}
|
||||
Keep · {proposed ? group.survivor_reason : 'your pick'}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -151,6 +151,15 @@ describe('admin duplicates', () => {
|
||||
expect(rows[1].querySelector('[data-testid="survivor-badge"]')).toBeNull();
|
||||
});
|
||||
|
||||
test('picking another copy moves the keep badge to it', async () => {
|
||||
renderWith(response());
|
||||
const rows = screen.getAllByTestId('duplicate-member');
|
||||
await fireEvent.click(rows[1].querySelector('input[type="radio"]') as HTMLInputElement);
|
||||
const after = screen.getAllByTestId('duplicate-member');
|
||||
expect(after[0].querySelector('[data-testid="survivor-badge"]')).toBeNull();
|
||||
expect(text(after[1].querySelector('[data-testid="survivor-badge"]') as HTMLElement)).toBe('Keep · your pick');
|
||||
});
|
||||
|
||||
test('an acoustic group reads as a match percentage', () => {
|
||||
const r = response();
|
||||
r.groups[0] = { ...r.groups[0], tier: 'acoustic', worst_bit_error_rate: 0.04 };
|
||||
|
||||
Reference in New Issue
Block a user