From 20e50156a264ab8b22c1e04bcd7a4b9be17c65e0 Mon Sep 17 00:00:00 2001 From: pixelpaws Date: Fri, 27 Mar 2026 19:28:58 +0800 Subject: [PATCH] fix(recipes): allow Enter to add import tags --- .../js/managers/import/RecipeDataManager.js | 19 +++++++ .../RecipeDataManager.tagInput.test.js | 56 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 tests/frontend/managers/RecipeDataManager.tagInput.test.js diff --git a/static/js/managers/import/RecipeDataManager.js b/static/js/managers/import/RecipeDataManager.js index 63668410..319d3419 100644 --- a/static/js/managers/import/RecipeDataManager.js +++ b/static/js/managers/import/RecipeDataManager.js @@ -6,8 +6,27 @@ export class RecipeDataManager { this.importManager = importManager; } + setupTagInputEnterHandler() { + const tagInput = document.getElementById('tagInput'); + if (!tagInput || tagInput.hasEnterAddTagHandler) { + return; + } + + tagInput.addEventListener('keydown', (event) => { + if (event.key !== 'Enter') { + return; + } + + event.preventDefault(); + this.addTag(); + }); + + tagInput.hasEnterAddTagHandler = true; + } + showRecipeDetailsStep() { this.importManager.stepManager.showStep('detailsStep'); + this.setupTagInputEnterHandler(); // Set default recipe name from prompt or image filename const recipeName = document.getElementById('recipeName'); diff --git a/tests/frontend/managers/RecipeDataManager.tagInput.test.js b/tests/frontend/managers/RecipeDataManager.tagInput.test.js new file mode 100644 index 00000000..329def6d --- /dev/null +++ b/tests/frontend/managers/RecipeDataManager.tagInput.test.js @@ -0,0 +1,56 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +vi.mock('../../../static/js/utils/uiHelpers.js', () => ({ + showToast: vi.fn(), +})); + +vi.mock('../../../static/js/utils/i18nHelpers.js', () => ({ + translate: (_key, _params, fallback) => fallback ?? '', +})); + +describe('RecipeDataManager tag input Enter behavior', () => { + beforeEach(() => { + vi.resetModules(); + document.body.innerHTML = ` + +
+ `; + }); + + it('adds a tag when pressing Enter in tag input', async () => { + const { RecipeDataManager } = await import('../../../static/js/managers/import/RecipeDataManager.js'); + const importManager = { + recipeTags: [], + stepManager: { showStep: vi.fn() }, + }; + const manager = new RecipeDataManager(importManager); + + manager.setupTagInputEnterHandler(); + + const tagInput = document.getElementById('tagInput'); + tagInput.value = 'portrait'; + tagInput.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })); + + expect(importManager.recipeTags).toEqual(['portrait']); + expect(tagInput.value).toBe(''); + expect(document.getElementById('tagsContainer').textContent).toContain('portrait'); + }); + + it('does not register duplicate Enter handlers when setup runs multiple times', async () => { + const { RecipeDataManager } = await import('../../../static/js/managers/import/RecipeDataManager.js'); + const importManager = { + recipeTags: [], + stepManager: { showStep: vi.fn() }, + }; + const manager = new RecipeDataManager(importManager); + + manager.setupTagInputEnterHandler(); + manager.setupTagInputEnterHandler(); + + const tagInput = document.getElementById('tagInput'); + tagInput.value = 'anime'; + tagInput.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true })); + + expect(importManager.recipeTags).toEqual(['anime']); + }); +});