diff --git a/js/tools/SpellingAlphabetTool.js b/js/tools/SpellingAlphabetTool.js index f4d723d..91991bb 100644 --- a/js/tools/SpellingAlphabetTool.js +++ b/js/tools/SpellingAlphabetTool.js @@ -207,6 +207,14 @@ class SpellingAlphabetTool extends Tool { return 'Enter a name for this spelling alphabet.'; } + var duplicateName = (this.saAlphabets || []).some(function(entry) { + return entry.id !== this.saEditingId && + String(entry.name || '').trim().toLowerCase() === name.toLowerCase(); + }, this); + if (duplicateName) { + return 'Another spelling alphabet already uses this name. Choose a unique name.'; + } + var missing = this.saLetters.filter(function(letter) { return !String(this.saAlphabet[letter] || '').trim(); }, this); @@ -295,6 +303,9 @@ class SpellingAlphabetTool extends Tool { onActivate(vueInstance) { vueInstance.saLoadAlphabets(); + if (typeof vueInstance.refreshCustomSpellingTransforms === 'function') { + vueInstance.refreshCustomSpellingTransforms(); + } } } diff --git a/js/tools/TransformTool.js b/js/tools/TransformTool.js index cac2b0f..939d1ca 100644 --- a/js/tools/TransformTool.js +++ b/js/tools/TransformTool.js @@ -76,6 +76,8 @@ class TransformTool extends Tool { return true; }) .map(([key, transform]) => ({ + transformKey: key, + customSpellingId: transform.customSpellingId || null, name: transform.name, func: transform.func.bind(transform), preview: transform.preview ? transform.preview.bind(transform) : function() { return '[preview]'; }, @@ -248,6 +250,12 @@ class TransformTool extends Tool { const transform = this.transforms.find(t => t.name === transformName); return transform ? transform.category : 'special'; }, + getTransformKey: function(transform) { + if (!transform) { + return ''; + } + return transform.customSpellingId || transform.transformKey || transform.name; + }, /** * True if this transform should show the options gear (uses saved prefs + defaults in decoder). * Falls back to window.transforms when the Vue copy omits configurableOptions. @@ -644,11 +652,22 @@ class TransformTool extends Tool { return; } + const previousCustomCount = (this.transforms || []).filter(function(t) { + return t.category === 'custom_spelling'; + }).length; + this.transforms = transformTool.buildTransformsFromWindow(); const categories = transformTool.rebuildTransformCategories(this.transforms); this.legendCategories = categories.legendCategories; this.categories = categories.sectionCategories; + const nextCustomCount = this.transforms.filter(function(t) { + return t.category === 'custom_spelling'; + }).length; + if (nextCustomCount !== previousCustomCount) { + this.saveCategoryOrder(this.categories); + } + this.$nextTick(() => { if (typeof this.initializeCategoryNavigation === 'function') { this.initializeCategoryNavigation(); @@ -719,6 +738,9 @@ class TransformTool extends Tool { getVueLifecycle() { return { mounted() { + if (typeof this.refreshCustomSpellingTransforms === 'function') { + this.refreshCustomSpellingTransforms(); + } this.initializeCategoryNavigation(); // Save initial category order to localStorage if it doesn't exist @@ -736,6 +758,9 @@ class TransformTool extends Tool { } onActivate(vueInstance) { + if (typeof vueInstance.refreshCustomSpellingTransforms === 'function') { + vueInstance.refreshCustomSpellingTransforms(); + } vueInstance.$nextTick(() => { vueInstance.initializeCategoryNavigation(); }); diff --git a/templates/transforms.html b/templates/transforms.html index 175f941..b735719 100644 --- a/templates/transforms.html +++ b/templates/transforms.html @@ -416,7 +416,7 @@