diff --git a/src/utils/tagManipulation.js b/src/utils/tagManipulation.js index 53e5908..ccf5490 100644 --- a/src/utils/tagManipulation.js +++ b/src/utils/tagManipulation.js @@ -2,8 +2,6 @@ import validTagsList from "../../.github/actions/validTagsList.json"; import possibleTagColors from "./tagColors.json"; import { allLabNamesAndUrls } from "../data/labNamesUrls"; -const tagKeyNames = Object.keys(validTagsList); - // Used in the filter menu to add/remove params // Used when clicking on a tag to remove all params and add only the one clicked export function updateSearchParamUrl(urlStringToUpdate, tagInput) { @@ -29,56 +27,33 @@ export function getBackgroundColor(key) { return index >= 0 ? possibleTagColors[index] : "#6ebebd"; } -// Takes in a content collection object (e.g., projects or ecosystems) and returns an object of only the unique tag keys and unique tag values within each key +// Takes in a content collection object (e.g., projects or ecosystems) and returns +// an object of only the unique tag keys and unique tag values within each key // All returned keys and tags are lowercase // Keys are in the order set by validTagsList. Tags are in alphabetical order // Used to create the tag categories and tag option list in the filter menu -export function extractUniqueTagsObject(contentCollectionObj) { - const uniqueTags = {}; - //Ensure contentCollectionObj is always treated as an array, to handle cases where the length is 1 - const normalizedCollection = Array.isArray(contentCollectionObj) - ? contentCollectionObj - : [contentCollectionObj]; +export function extractUniqueTagsObject(contentCollection) { + const uniqueTags = {}; + const validTagKeys = Object.keys(validTagsList); - normalizedCollection.forEach((contentItem) => { - Object.entries(contentItem.data).forEach(([key, value]) => { - // tagKeyNames are the keys of validTagsList, imported at the top of the file - // If the current key is a value in tagKeyNames, we want to check if the key exists in uniqueTags - const isTagKey = tagKeyNames.some((tagKeyName) => tagKeyName === key); - if (isTagKey) { - //only process if the key has a value. User could have left it blank. - if (value) { - // process for if the value of key is an array (can also be a string - see else statement below) - if (Array.isArray(value)) { - value.forEach((tagValue) => { - // if the key doesn't exist in uniqueTags, add it and set it equal to the current tag value - if (!uniqueTags[key]) { - uniqueTags[key] = [tagValue]; - } else { - // if the key does exist in uniqueTags, check whether the current tag value exists. If not, add the current tag value - if (!uniqueTags[key].includes(tagValue)) { - uniqueTags[key].push(tagValue); - } - } - }); - } else { - //process for if the value of key is a string - this is a valid tag input from users in the MD files. - //this is the same process as found in the forEach loop above - if (!uniqueTags[key]) { - uniqueTags[key] = [value]; - } else { - if (!uniqueTags[key].includes(value)) { - uniqueTags[key].push(value); - } - } - } - } + // For each key, determine the union of all unique values associated with it + // (across all content items), excluding keys which aren't in validTagsList. + contentCollection = Array.isArray(contentCollection) ? contentCollection : [contentCollection]; + contentCollection.forEach((contentItem) => { + Object.entries(contentItem.data).forEach(([key, tagValues]) => { + if (!validTagKeys.includes(key) || !tagValues || !tagValues.length) { + return; } + tagValues = Array.isArray(tagValues) ? tagValues : [tagValues]; + tagValues.forEach((tv) => { + (uniqueTags[key] ??= new Set()).add(tv); + }); }); }); - // Alphabetize the values in the array within each key + + // Convert from Sets to sorted Arrays Object.keys(uniqueTags).forEach((key) => { - uniqueTags[key].sort(); + uniqueTags[key] = Array.from(uniqueTags[key]).sort(); }); return uniqueTags; } @@ -90,6 +65,7 @@ export function extractUniqueTagValueArray(projectData) { Object.entries(projectData).forEach(([key, value]) => { // If the current projectData key is a value in the tagKeyNames array, and the key has some associated value, add to uniqueTagsObj + const tagKeyNames = Object.keys(validTagsList); const isTagKey = tagKeyNames.some((tagKeyName) => tagKeyName === key); if (isTagKey) { if (value) {