From 95035e5eace68ec839ed173d4c8b1f32d4b510af Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 9 Dec 2025 20:30:40 +0100 Subject: [PATCH 1/3] Added a wikilinks option to property mappings section WIP, known bug: the checkboxes don't reflect the state when obsidian restarts --- src/settings/PropertyMapper.ts | 14 +++++- src/settings/PropertyMapping.ts | 6 ++- .../PropertyMappingModelComponent.svelte | 42 ++++++++++++------ src/settings/Settings.ts | 44 +++++++++++++++++-- 4 files changed, 85 insertions(+), 21 deletions(-) diff --git a/src/settings/PropertyMapper.ts b/src/settings/PropertyMapper.ts index 533399c..a6f4e13 100644 --- a/src/settings/PropertyMapper.ts +++ b/src/settings/PropertyMapper.ts @@ -35,14 +35,24 @@ export class PropertyMapper { for (const [key, value] of Object.entries(obj)) { for (const propertyMapping of propertyMappings) { if (propertyMapping.property === key) { + let finalValue = value; + if (propertyMapping.wikilink) { + if (typeof value === 'string') { + finalValue = `[[${value}]]`; + } else if (Array.isArray(value)) { + finalValue = value.map(v => + typeof v === 'string' ? `[[${v}]]` : v + ); + } + } if (propertyMapping.mapping === PropertyMappingOption.Map) { // @ts-ignore - newObj[propertyMapping.newProperty] = value; + newObj[propertyMapping.newProperty] = finalValue; } else if (propertyMapping.mapping === PropertyMappingOption.Remove) { // do nothing } else if (propertyMapping.mapping === PropertyMappingOption.Default) { // @ts-ignore - newObj[key] = value; + newObj[key] = finalValue; } break; } diff --git a/src/settings/PropertyMapping.ts b/src/settings/PropertyMapping.ts index bad0369..730b579 100644 --- a/src/settings/PropertyMapping.ts +++ b/src/settings/PropertyMapping.ts @@ -75,7 +75,7 @@ export class PropertyMappingModel { copy(): PropertyMappingModel { const copy = new PropertyMappingModel(this.type); for (const property of this.properties) { - const propertyCopy = new PropertyMapping(property.property, property.newProperty, property.mapping, property.locked); + const propertyCopy = new PropertyMapping(property.property, property.newProperty, property.mapping, property.locked, property.wikilink); copy.properties.push(propertyCopy); } return copy; @@ -87,12 +87,14 @@ export class PropertyMapping { newProperty: string; locked: boolean; mapping: PropertyMappingOption; + wikilink: boolean; - constructor(property: string, newProperty: string, mapping: PropertyMappingOption, locked?: boolean) { + constructor(property: string, newProperty: string, mapping: PropertyMappingOption, locked?: boolean, wikilink?: boolean) { this.property = property; this.newProperty = newProperty; this.mapping = mapping; this.locked = locked ?? false; + this.wikilink = wikilink ?? false; } validate(): { res: boolean; err?: Error } { diff --git a/src/settings/PropertyMappingModelComponent.svelte b/src/settings/PropertyMappingModelComponent.svelte index 81b236c..fb6707e 100644 --- a/src/settings/PropertyMappingModelComponent.svelte +++ b/src/settings/PropertyMappingModelComponent.svelte @@ -27,20 +27,27 @@ {#if property.locked}
property cannot be remapped
{:else} - - - {#if property.mapping === PropertyMappingOption.Map} - -
- -
- {/if} +
+ + {#if property.mapping === PropertyMappingOption.Map} + +
+ +
+ {/if} + + +
{/if} {/each} @@ -64,4 +71,11 @@ diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 1838026..1cf540a 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -155,16 +155,54 @@ export function getDefaultSettings(plugin: MediaDbPlugin): MediaDbPluginSettings const propertyMappingModel: PropertyMappingModel = new PropertyMappingModel(mediaType); for (const key of Object.keys(metadataObj)) { - propertyMappingModel.properties.push(new PropertyMapping(key, '', PropertyMappingOption.Default, lockedPropertyMappings.contains(key))); + propertyMappingModel.properties.push( + new PropertyMapping( + key, + '', + PropertyMappingOption.Default, + lockedPropertyMappings.contains(key), + false, // wikilink default + ) + ); } propertyMappingModels.push(propertyMappingModel); } + // MIGRATION: Ensure all property mappings have wikilink defined (for settings loaded from disk) + if (defaultSettings.propertyMappingModels && Array.isArray(defaultSettings.propertyMappingModels)) { + for (const model of defaultSettings.propertyMappingModels) { + if (model.properties && Array.isArray(model.properties)) { + for (const prop of model.properties) { + if (typeof prop.wikilink === 'undefined') { + prop.wikilink = false; + } + } + } + } + } + defaultSettings.propertyMappingModels = propertyMappingModels; return defaultSettings; } +/** + * Ensures all property mappings in loaded settings have the wikilink property defined. + */ +export function ensureWikilinkOnPropertyMappings(settings: MediaDbPluginSettings): void { + if (settings.propertyMappingModels && Array.isArray(settings.propertyMappingModels)) { + for (const model of settings.propertyMappingModels) { + if (model.properties && Array.isArray(model.properties)) { + for (const prop of model.properties) { + if (typeof prop.wikilink === 'undefined') { + prop.wikilink = false; + } + } + } + } + } +} + export class MediaDbSettingTab extends PluginSettingTab { plugin: MediaDbPlugin; @@ -779,8 +817,8 @@ export class MediaDbSettingTab extends PluginSettingTab { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.boardgameFileNameTemplate}`) .setValue(this.plugin.settings.boardgameFileNameTemplate) .onChange(data => { - this.plugin.settings.boardgameFileNameTemplate = data; - void this.plugin.saveSettings(); + this.plugin.settings.boardgameFileNameTemplate = data; + void this.plugin.saveSettings(); }); }); From f8b6ae8761c16fcf3dcdfa5af8f3f55438e32dd8 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 9 Dec 2025 21:07:45 +0100 Subject: [PATCH 2/3] Fix checkbox state not updating + ran prettier Forgot a comma and to load back the wikilink with new properties --- src/main.ts | 4 +++- src/settings/PropertyMapper.ts | 4 +--- src/settings/PropertyMappingModelComponent.svelte | 14 +++++++------- src/settings/Settings.ts | 6 +++--- src/settings/suggesters/FileSuggest.ts | 3 ++- src/settings/suggesters/FolderSuggest.ts | 3 ++- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/main.ts b/src/main.ts index 4c69dc4..faaf025 100644 --- a/src/main.ts +++ b/src/main.ts @@ -584,7 +584,9 @@ export default class MediaDbPlugin extends Plugin { newProperties.push(defaultProperty); } else { // newProperty is just an object and take locked status from default property - newProperties.push(new PropertyMapping(newProperty.property, newProperty.newProperty, newProperty.mapping, defaultProperty.locked)); + newProperties.push( + new PropertyMapping(newProperty.property, newProperty.newProperty, newProperty.mapping, defaultProperty.locked, newProperty.wikilink ?? false), + ); } } diff --git a/src/settings/PropertyMapper.ts b/src/settings/PropertyMapper.ts index a6f4e13..b2cabd7 100644 --- a/src/settings/PropertyMapper.ts +++ b/src/settings/PropertyMapper.ts @@ -40,9 +40,7 @@ export class PropertyMapper { if (typeof value === 'string') { finalValue = `[[${value}]]`; } else if (Array.isArray(value)) { - finalValue = value.map(v => - typeof v === 'string' ? `[[${v}]]` : v - ); + finalValue = value.map(v => (typeof v === 'string' ? `[[${v}]]` : v)); } } if (propertyMapping.mapping === PropertyMappingOption.Map) { diff --git a/src/settings/PropertyMappingModelComponent.svelte b/src/settings/PropertyMappingModelComponent.svelte index fb6707e..2b0269a 100644 --- a/src/settings/PropertyMappingModelComponent.svelte +++ b/src/settings/PropertyMappingModelComponent.svelte @@ -71,11 +71,11 @@ diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 1cf540a..98ddfe2 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -162,7 +162,7 @@ export function getDefaultSettings(plugin: MediaDbPlugin): MediaDbPluginSettings PropertyMappingOption.Default, lockedPropertyMappings.contains(key), false, // wikilink default - ) + ), ); } @@ -817,8 +817,8 @@ export class MediaDbSettingTab extends PluginSettingTab { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.boardgameFileNameTemplate}`) .setValue(this.plugin.settings.boardgameFileNameTemplate) .onChange(data => { - this.plugin.settings.boardgameFileNameTemplate = data; - void this.plugin.saveSettings(); + this.plugin.settings.boardgameFileNameTemplate = data; + void this.plugin.saveSettings(); }); }); diff --git a/src/settings/suggesters/FileSuggest.ts b/src/settings/suggesters/FileSuggest.ts index 1caa448..6bbdb96 100644 --- a/src/settings/suggesters/FileSuggest.ts +++ b/src/settings/suggesters/FileSuggest.ts @@ -5,7 +5,8 @@ export class FileSuggest extends AbstractInputSuggest { const lowerCaseInputStr = query.toLowerCase(); // we do two filters because otherwise TS type inference does convert the array to TFile[] - return this.app.vault.getAllLoadedFiles() + return this.app.vault + .getAllLoadedFiles() .filter(file => file instanceof TFile) .filter(file => file.path.toLowerCase().contains(lowerCaseInputStr)); } diff --git a/src/settings/suggesters/FolderSuggest.ts b/src/settings/suggesters/FolderSuggest.ts index 183a2cd..eaee715 100644 --- a/src/settings/suggesters/FolderSuggest.ts +++ b/src/settings/suggesters/FolderSuggest.ts @@ -5,7 +5,8 @@ export class FolderSuggest extends AbstractInputSuggest { const lowerCaseInputStr = query.toLowerCase(); // we do two filters because otherwise TS type inference does convert the array to TFolder[] - return this.app.vault.getAllLoadedFiles() + return this.app.vault + .getAllLoadedFiles() .filter(file => file instanceof TFolder) .filter(file => file.path.toLowerCase().contains(lowerCaseInputStr)); } From b2835dc6e345e3806add7c94b725beef8a387187 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Wed, 10 Dec 2025 01:30:19 +0100 Subject: [PATCH 3/3] Property mapping section Table view --- .../PropertyMappingModelComponent.svelte | 160 +++++++++++++----- 1 file changed, 117 insertions(+), 43 deletions(-) diff --git a/src/settings/PropertyMappingModelComponent.svelte b/src/settings/PropertyMappingModelComponent.svelte index 2b0269a..7dca2d5 100644 --- a/src/settings/PropertyMappingModelComponent.svelte +++ b/src/settings/PropertyMappingModelComponent.svelte @@ -11,71 +11,145 @@ let { model, save }: Props = $props(); let validationResult: { res: boolean; err?: Error } | undefined = $derived(model.validate()); - - // Use $state as a variable declaration initializer - let propertyStates = $state(model.properties.map(p => ({ ...p })));
{capitalizeFirstLetter(model.type)}
-
- {#each propertyStates as property, i} -
-
-
{property.property}
-
- {#if property.locked} -
property cannot be remapped
- {:else} -
- - {#if property.mapping === PropertyMappingOption.Map} - -
- -
- {/if} - - -
- {/if} -
- {/each} -
+ + + + + + + + + + + + {#each model.properties as property} + + + + {#if property.locked} + + {:else} + + + + + + {/if} + + {/each} + +
PropertyMappingNew nameWikilink
+ {property.property} + +
property cannot be remapped
+
+ + + {#if property.mapping === PropertyMappingOption.Map} +
+ + +
+ {:else} + + {/if} +
+ {#if !validationResult?.res}
{validationResult?.err?.message}
{/if} +