mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-27 21:20:53 +01:00
fix: require media management settings before quality profile sync
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user