diff --git a/.changelog/current/2470-uniq-keywords-and-categories.md b/.changelog/current/2470-uniq-keywords-and-categories.md new file mode 100644 index 000000000..02b3816a8 --- /dev/null +++ b/.changelog/current/2470-uniq-keywords-and-categories.md @@ -0,0 +1,4 @@ +Author: @nathanielhourt + +# Fixed +- Prevent duplicated keywords and categories that differ only in case diff --git a/src/composables/useRecipeFilterControls/index.js b/src/composables/useRecipeFilterControls/index.js index 90a5af256..be1c45a45 100644 --- a/src/composables/useRecipeFilterControls/index.js +++ b/src/composables/useRecipeFilterControls/index.js @@ -10,6 +10,15 @@ import { AndOperator, OrOperator } from '../../js/LogicOperators'; export default function useRecipeFilterControls(props) { const store = useStore(); + // Helper method that sorts strings case insensitively + const caseInsensitiveSort = (a, b) => { + const aUpper = a.toUpperCase(); + const bUpper = b.toUpperCase(); + if (aUpper < bUpper) return -1; + if (bUpper < aUpper) return 1; + return 0; + }; + /** * @type {import('vue').Ref} */ @@ -114,7 +123,9 @@ export default function useRecipeFilterControls(props) { * A unique set of all categories in the recipes. * @type {import('vue').ComputedRef>} */ - const uniqueCategories = computed(() => [...new Set(rawCategories.value)]); + const uniqueCategories = computed(() => + [...new Set(rawCategories.value)].sort(caseInsensitiveSort), + ); /** * An array of all keywords in the recipes. These are neither sorted nor unique @@ -133,9 +144,11 @@ export default function useRecipeFilterControls(props) { }); /** - * A unique set of all keywords in all recipes. + * A unique and sorted set of all keywords in all recipes. */ - const uniqueKeywords = computed(() => [...new Set(rawKeywords.value)]); + const uniqueKeywords = computed(() => + [...new Set(rawKeywords.value)].sort(caseInsensitiveSort), + ); return { uniqueCategories,