From 56cf061a4bcf50482a6ae34a1428e0c0e620307d Mon Sep 17 00:00:00 2001 From: Sam Chau Date: Wed, 31 Dec 2025 03:31:59 +1030 Subject: [PATCH] feat(customFormats): implement general queries and update related types and components --- .../pcd/queries/customFormats/general.ts | 43 ++++++++++++ .../server/pcd/queries/customFormats/index.ts | 3 +- .../server/pcd/queries/customFormats/tests.ts | 9 ++- .../server/pcd/queries/customFormats/types.ts | 10 +++ src/lib/server/pcd/schema.ts | 1 + .../[databaseId]/[id]/general/+page.server.ts | 4 +- .../[databaseId]/[id]/general/+page.svelte | 69 ++++++++++++++++++- 7 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 src/lib/server/pcd/queries/customFormats/general.ts diff --git a/src/lib/server/pcd/queries/customFormats/general.ts b/src/lib/server/pcd/queries/customFormats/general.ts new file mode 100644 index 0000000..7d25b7b --- /dev/null +++ b/src/lib/server/pcd/queries/customFormats/general.ts @@ -0,0 +1,43 @@ +/** + * Custom format general queries + */ + +import type { PCDCache } from '../../cache.ts'; +import type { CustomFormatGeneral } from './types.ts'; + +/** + * Get general information for a single custom format + */ +export async function general(cache: PCDCache, formatId: number): Promise { + const db = cache.kb; + + // Get the custom format + const format = await db + .selectFrom('custom_formats') + .select(['id', 'name', 'description', 'include_in_rename']) + .where('id', '=', formatId) + .executeTakeFirst(); + + if (!format) return null; + + // Get tags for this format + const tags = await db + .selectFrom('custom_format_tags as cft') + .innerJoin('tags as t', 't.id', 'cft.tag_id') + .select(['t.id as tag_id', 't.name as tag_name', 't.created_at as tag_created_at']) + .where('cft.custom_format_id', '=', formatId) + .orderBy('t.name') + .execute(); + + return { + id: format.id, + name: format.name, + description: format.description || '', + include_in_rename: format.include_in_rename === 1, + tags: tags.map((tag) => ({ + id: tag.tag_id, + name: tag.tag_name, + created_at: tag.tag_created_at + })) + }; +} diff --git a/src/lib/server/pcd/queries/customFormats/index.ts b/src/lib/server/pcd/queries/customFormats/index.ts index 0f329eb..479c6c4 100644 --- a/src/lib/server/pcd/queries/customFormats/index.ts +++ b/src/lib/server/pcd/queries/customFormats/index.ts @@ -3,7 +3,7 @@ */ // Export all types -export type { CustomFormatTableRow, ConditionRef, CustomFormatBasic, CustomFormatTest } from './types.ts'; +export type { CustomFormatTableRow, ConditionRef, CustomFormatBasic, CustomFormatGeneral, CustomFormatTest } from './types.ts'; export type { CreateTestInput, CreateTestOptions } from './testCreate.ts'; export type { UpdateTestInput, UpdateTestOptions } from './testUpdate.ts'; export type { DeleteTestOptions } from './testDelete.ts'; @@ -12,6 +12,7 @@ export type { ConditionResult, EvaluationResult, ParsedInfo } from './evaluator. // Export query functions (reads) export { list } from './list.ts'; +export { general } from './general.ts'; export { getById, listTests, getTestById } from './tests.ts'; export { getConditionsForEvaluation } from './conditions.ts'; export { evaluateCustomFormat, getParsedInfo } from './evaluator.ts'; diff --git a/src/lib/server/pcd/queries/customFormats/tests.ts b/src/lib/server/pcd/queries/customFormats/tests.ts index ec18944..49a5dad 100644 --- a/src/lib/server/pcd/queries/customFormats/tests.ts +++ b/src/lib/server/pcd/queries/customFormats/tests.ts @@ -13,11 +13,16 @@ export async function getById(cache: PCDCache, formatId: number): Promise + import { Check } from 'lucide-svelte'; + import FormInput from '$ui/form/FormInput.svelte'; + import TagInput from '$ui/form/TagInput.svelte'; + import IconCheckbox from '$ui/form/IconCheckbox.svelte'; + import UnsavedChangesModal from '$ui/modal/UnsavedChangesModal.svelte'; + import { useUnsavedChanges } from '$lib/client/utils/unsavedChanges.svelte'; import type { PageData } from './$types'; export let data: PageData; + + const unsavedChanges = useUnsavedChanges(); + + let name = data.format.name; + let description = data.format.description; + let tags: string[] = data.format.tags.map((t) => t.name); + let includeInRename = data.format.include_in_rename; + + // Mark as dirty when any field changes + $: if ( + name !== data.format.name || + description !== data.format.description || + includeInRename !== data.format.include_in_rename + ) { + unsavedChanges.markDirty(); + } {data.format.name} - General - Profilarr + +
-

- General tab placeholder - conditions and settings will go here. -

+ + + + +
+
Tags
+

+ Add tags to organize and categorize this custom format. +

+ + 0 ? JSON.stringify(tags) : ''} /> +
+ +
+
+ Include In Rename +
+

+ When enabled, this custom format's name will be included in the renamed filename. +

+
+ (includeInRename = !includeInRename)} + /> + + {includeInRename ? 'Enabled' : 'Disabled'} + +
+