diff --git a/src/lib/client/assets/Radarr.svg b/src/lib/client/assets/Radarr.svg new file mode 100644 index 0000000..2f06f69 --- /dev/null +++ b/src/lib/client/assets/Radarr.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/lib/client/assets/Sonarr.svg b/src/lib/client/assets/Sonarr.svg new file mode 100644 index 0000000..b0a7218 --- /dev/null +++ b/src/lib/client/assets/Sonarr.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/routes/arr/+page.svelte b/src/routes/arr/+page.svelte index 6352a30..1de4d5f 100644 --- a/src/routes/arr/+page.svelte +++ b/src/routes/arr/+page.svelte @@ -1,5 +1,5 @@
- +
diff --git a/src/routes/databases/[id]/edit/+layout@.svelte b/src/routes/databases/[id]/edit/+layout@.svelte deleted file mode 100644 index af1293c..0000000 --- a/src/routes/databases/[id]/edit/+layout@.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/routes/databases/[id]/edit/+page.server.ts b/src/routes/databases/[id]/settings/+page.server.ts similarity index 67% rename from src/routes/databases/[id]/edit/+page.server.ts rename to src/routes/databases/[id]/settings/+page.server.ts index 3ddc879..ab45178 100644 --- a/src/routes/databases/[id]/edit/+page.server.ts +++ b/src/routes/databases/[id]/settings/+page.server.ts @@ -1,29 +1,9 @@ -import { error, redirect, fail } from '@sveltejs/kit'; -import type { ServerLoad, Actions } from '@sveltejs/kit'; +import { redirect, fail } from '@sveltejs/kit'; +import type { Actions } from '@sveltejs/kit'; import { databaseInstancesQueries } from '$db/queries/databaseInstances.ts'; import { pcdManager } from '$pcd/pcd.ts'; import { logger } from '$logger/logger.ts'; -export const load: ServerLoad = ({ params }) => { - const id = parseInt(params.id || '', 10); - - // Validate ID - if (isNaN(id)) { - error(404, `Invalid database ID: ${params.id}`); - } - - // Fetch the specific instance - const instance = databaseInstancesQueries.getById(id); - - if (!instance) { - error(404, `Database not found: ${id}`); - } - - return { - instance - }; -}; - export const actions: Actions = { update: async ({ params, request }) => { const id = parseInt(params.id || '', 10); @@ -31,7 +11,7 @@ export const actions: Actions = { // Validate ID if (isNaN(id)) { await logger.warn('Update failed: Invalid database ID', { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id: params.id } }); return fail(400, { error: 'Invalid database ID' }); @@ -42,7 +22,7 @@ export const actions: Actions = { if (!instance) { await logger.warn('Update failed: Database not found', { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id } }); return fail(404, { error: 'Database not found' }); @@ -59,7 +39,7 @@ export const actions: Actions = { // Validation if (!name) { await logger.warn('Attempted to update database with missing required fields', { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id, name } }); @@ -70,13 +50,9 @@ export const actions: Actions = { } // Check if name already exists (excluding current instance) - const existingWithName = databaseInstancesQueries - .getAll() - .find((db) => db.name === name && db.id !== id); - - if (existingWithName) { + if (databaseInstancesQueries.nameExists(name, id)) { await logger.warn('Attempted to update database with duplicate name', { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id, name } }); @@ -100,21 +76,15 @@ export const actions: Actions = { } await logger.info(`Updated database: ${name}`, { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id, name } }); - // Redirect to database detail page - redirect(303, `/databases/${id}`); - } catch (error) { - // Re-throw redirect errors (they're not actual errors) - if (error && typeof error === 'object' && 'status' in error && 'location' in error) { - throw error; - } - + return { success: true }; + } catch (err) { await logger.error('Failed to update database', { - source: 'databases/[id]/edit', - meta: { error: error instanceof Error ? error.message : String(error) } + source: 'databases/[id]/settings', + meta: { error: err instanceof Error ? err.message : String(err) } }); return fail(500, { @@ -130,7 +100,7 @@ export const actions: Actions = { // Validate ID if (isNaN(id)) { await logger.warn('Delete failed: Invalid database ID', { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id: params.id } }); return fail(400, { error: 'Invalid database ID' }); @@ -141,7 +111,7 @@ export const actions: Actions = { if (!instance) { await logger.warn('Delete failed: Database not found', { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id } }); return fail(404, { error: 'Database not found' }); @@ -152,21 +122,21 @@ export const actions: Actions = { await pcdManager.unlink(id); await logger.info(`Unlinked database: ${instance.name}`, { - source: 'databases/[id]/edit', + source: 'databases/[id]/settings', meta: { id, name: instance.name, repositoryUrl: instance.repository_url } }); // Redirect to databases list redirect(303, '/databases'); - } catch (error) { + } catch (err) { // Re-throw redirect errors (they're not actual errors) - if (error && typeof error === 'object' && 'status' in error && 'location' in error) { - throw error; + if (err && typeof err === 'object' && 'status' in err && 'location' in err) { + throw err; } await logger.error('Failed to unlink database', { - source: 'databases/[id]/edit', - meta: { error: error instanceof Error ? error.message : String(error) } + source: 'databases/[id]/settings', + meta: { error: err instanceof Error ? err.message : String(err) } }); return fail(500, { error: 'Failed to unlink database' }); diff --git a/src/routes/databases/[id]/edit/+page.svelte b/src/routes/databases/[id]/settings/+page.svelte similarity index 58% rename from src/routes/databases/[id]/edit/+page.svelte rename to src/routes/databases/[id]/settings/+page.svelte index 230fb97..25a5d63 100644 --- a/src/routes/databases/[id]/edit/+page.svelte +++ b/src/routes/databases/[id]/settings/+page.svelte @@ -6,4 +6,8 @@ export let data: PageData; - + + {data.database.name} - Settings - Profilarr + + + diff --git a/src/routes/databases/components/InstanceForm.svelte b/src/routes/databases/components/InstanceForm.svelte index 0a2f1e1..f9689f1 100644 --- a/src/routes/databases/components/InstanceForm.svelte +++ b/src/routes/databases/components/InstanceForm.svelte @@ -1,9 +1,15 @@ -
-
-

{title}

-

- {description} -

+
+ +
+
+

{title}

+

{description}

+
+
+ {#if mode === 'edit'} +
+
+ + update('name', e.detail)} + /> + + + update('repositoryUrl', e.detail)} + /> + + + {#if mode === 'create'} + update('branch', e.detail)} + /> + {/if} + + + update('personalAccessToken', e.detail)} + /> + + +
+ +

+ How often to check for updates from the remote repository +

+ update('syncStrategy', e.detail)} + /> +
+ + +
+ +

+ Automatically pull updates when available, or just receive notifications +

+ update('autoPull', e.detail)} + /> +
+ {#if autoPull === 'false'} +

+ You will receive notifications when updates are available but they won't be applied + automatically +

+ {/if} +
+
+ + + + + +{#if mode === 'edit'}
{ - isLoading = true; + deleting = true; return async ({ result, update }) => { if (result.type === 'failure' && result.data) { - alertStore.add('error', (result.data as { error?: string }).error || errorMessage); + alertStore.add( + 'error', + (result.data as { error?: string }).error || 'Failed to unlink database' + ); } else if (result.type === 'redirect') { - // Don't show success message if redirecting to bruh page - if (result.location && !result.location.includes('/databases/bruh')) { - alertStore.add('success', successMessage); - } + alertStore.add('success', 'Database unlinked successfully'); } await update(); - isLoading = false; + deleting = false; }; }} - > - -
-

- Database Details -

- -
- -
- - -

- A friendly name to identify this database -

-
- - -
- - - {#if mode === 'edit'} -

- Repository URL cannot be changed after linking -

- {:else} -

- Git repository URL containing the PCD manifest -

- {/if} -
- - - {#if mode === 'create'} -
- - -

- Branch to checkout on link. Leave empty to use the default branch. You can change this - later. -

-
- {/if} - - -
- - -

- Required for private repositories to clone and for developers to push back to GitHub. -

-
-
-
- - -
-

- Sync Settings -

- -
- -
- - -

- How often to check for updates from the remote repository -

-
- - -
- -
- -

- If enabled, updates will be pulled automatically. If disabled, you'll only receive - notifications when updates are available. -

-
-
-
-
- - -
- {#if mode === 'edit'} - - Cancel - - {/if} - -
-
- - - {#if mode === 'edit'} -
-

Danger Zone

-

- Once you unlink this database, there is no going back. All local data will be removed. -

- - - -
- {/if} -
+ > +{/if} {#if mode === 'edit'} @@ -348,8 +305,13 @@ confirmDanger={true} on:confirm={() => { showDeleteModal = false; - deleteFormElement?.requestSubmit(); + const deleteForm = document.getElementById('delete-form'); + if (deleteForm instanceof HTMLFormElement) { + deleteForm.requestSubmit(); + } }} on:cancel={() => (showDeleteModal = false)} /> {/if} + + diff --git a/src/routes/databases/new/+page.svelte b/src/routes/databases/new/+page.svelte index f797bc8..4fde2a3 100644 --- a/src/routes/databases/new/+page.svelte +++ b/src/routes/databases/new/+page.svelte @@ -6,4 +6,10 @@ export let data: PageData; - + + Link Database - Profilarr + + +
+ +