fix: require media management settings before quality profile sync

This commit is contained in:
Sam Chau
2026-01-18 18:10:53 +10:30
parent 6bc72b032d
commit 5c529e665a
7 changed files with 52 additions and 1230 deletions

View File

@@ -55,6 +55,27 @@
} else {
initEdit({});
}
// Validation: Quality profiles require media management settings (saved, not dirty)
$: hasQualityProfilesSelected = Object.values(qualityProfileState).some((db) =>
Object.values(db).some((selected) => selected)
);
$: hasMediaManagement =
mediaManagementState.namingDatabaseId !== null &&
mediaManagementState.qualityDefinitionsDatabaseId !== null &&
mediaManagementState.mediaSettingsDatabaseId !== null;
$: qualityProfilesCanSave =
!hasQualityProfilesSelected || (hasMediaManagement && !mediaManagementDirty);
$: qualityProfilesWarning = !hasQualityProfilesSelected
? null
: !hasMediaManagement
? 'Quality profiles require media management settings. Configure media management settings above.'
: mediaManagementDirty
? 'Save your media management settings before saving quality profiles.'
: null;
</script>
<svelte:head>
@@ -82,12 +103,21 @@
</button>
</div>
<MediaManagement
databases={data.databases}
bind:state={mediaManagementState}
bind:syncTrigger={mediaManagementTrigger}
bind:cronExpression={mediaManagementCron}
bind:isDirty={mediaManagementDirty}
/>
<QualityProfiles
databases={data.databases}
bind:state={qualityProfileState}
bind:syncTrigger={qualityProfileTrigger}
bind:cronExpression={qualityProfileCron}
bind:isDirty={qualityProfilesDirty}
canSave={qualityProfilesCanSave}
warning={qualityProfilesWarning}
/>
<DelayProfiles
databases={data.databases}
@@ -96,13 +126,6 @@
bind:cronExpression={delayProfileCron}
bind:isDirty={delayProfilesDirty}
/>
<MediaManagement
databases={data.databases}
bind:state={mediaManagementState}
bind:syncTrigger={mediaManagementTrigger}
bind:cronExpression={mediaManagementCron}
bind:isDirty={mediaManagementDirty}
/>
</div>
<InfoModal bind:open={showInfoModal} header="How Sync Works">
@@ -121,6 +144,13 @@
</p>
</div>
<div>
<div class="font-medium text-neutral-900 dark:text-neutral-100">Media Management First</div>
<p class="mt-1">
Quality profiles require all media management settings (naming, quality definitions, and media settings) to be configured and saved first. This ensures your files are named consistently with what the profile expects.
</p>
</div>
<div class="border-t border-neutral-200 pt-4 dark:border-neutral-700">
<div class="font-medium text-neutral-900 dark:text-neutral-100 mb-3">Sync Methods</div>

View File

@@ -15,6 +15,8 @@
export let state: Record<number, Record<number, boolean>> = {};
export let syncTrigger: 'manual' | 'on_pull' | 'on_change' | 'schedule' = 'manual';
export let cronExpression: string = '0 * * * *';
export let canSave: boolean = true;
export let warning: string | null = null;
let saving = false;
let syncing = false;
@@ -147,5 +149,5 @@
{/if}
</div>
<SyncFooter bind:syncTrigger bind:cronExpression {saving} {syncing} {isDirty} on:save={handleSave} on:sync={handleSync} />
<SyncFooter bind:syncTrigger bind:cronExpression {saving} {syncing} {isDirty} {canSave} {warning} on:save={handleSave} on:sync={handleSync} />
</div>

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import IconCheckbox from '$ui/form/IconCheckbox.svelte';
import { Check, RefreshCw, Save, Loader2 } from 'lucide-svelte';
import { Check, RefreshCw, Save, Loader2, AlertTriangle } from 'lucide-svelte';
import { createEventDispatcher } from 'svelte';
export let syncTrigger: 'manual' | 'on_pull' | 'on_change' | 'schedule' = 'manual';
@@ -8,6 +8,8 @@
export let saving: boolean = false;
export let syncing: boolean = false;
export let isDirty: boolean = false;
export let canSave: boolean = true;
export let warning: string | null = null;
const dispatch = createEventDispatcher<{ save: void; sync: void }>();
@@ -18,8 +20,8 @@
{ value: 'schedule', label: 'Schedule' }
] as const;
// Save disabled when not dirty, Sync disabled when dirty (unsaved changes)
$: saveDisabled = saving || !isDirty;
// Save disabled when not dirty or can't save, Sync disabled when dirty (unsaved changes)
$: saveDisabled = saving || !isDirty || !canSave;
$: syncDisabled = syncing || isDirty;
</script>
@@ -49,7 +51,13 @@
{/if}
</div>
<div class="flex items-center gap-2">
<div class="flex items-center gap-3">
{#if warning}
<div class="flex items-center gap-1.5 text-xs text-amber-600 dark:text-amber-400">
<AlertTriangle size={14} class="flex-shrink-0" />
<span>{warning}</span>
</div>
{/if}
<button
type="button"
disabled={syncDisabled}