Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG FIX: Searches were not working with skill names #314

Merged
merged 2 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 114 additions & 42 deletions actions/skills/groupSkills.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,126 @@
import Skill from "@/types/skills";

const groupSkills = (
groupedBy: string,
skills: Skill[]
): Record<string, Skill[]> => {
let organizedSkills: Record<string, Skill[]> = {};
// Function to group skills by language
const groupByLanguage = (skills: Skill[]): Record<string, Skill[]> => {
// Filter skills to include only those categorized as "Programming Languages"
const programmingLanguages = skills.filter(
(skill) => skill.category === "Programming Languages",
);

const removeDuplicates = (skills: Skill[]): Skill[] => {
const skillSet = new Set();
const uniqueSkills: Skill[] = [];

skills.forEach((skill) => {
const serializedSkill = JSON.stringify(skill);
if (!skillSet.has(serializedSkill)) {
skillSet.add(serializedSkill);
uniqueSkills.push(skill);
// Reduce the filtered skills to group by language
return programmingLanguages.reduce(
(acc: Record<string, Skill[]>, languageSkill) => {
// The language's name serves as the key, and its technical skills are the group elements
if (languageSkill.name) {
acc[languageSkill.name] = removeDuplicates([
...(languageSkill.technicalGeneralSkills || []),
...(languageSkill.technicalHardSkills || []),
...(languageSkill.technicalSoftSkills || []),
]);
}
});
return acc;
},
{},
);
};

return uniqueSkills;
};
// Function to group skills by category
const groupByCategory = (skills: Skill[]): Record<string, Skill[]> => {
return skills.reduce((acc: Record<string, Skill[]>, skill) => {
const category = skill.category || "Other";
if (!acc[category]) {
acc[category] = [];
}
acc[category].push(skill);
return acc;
}, {});
};

// Function to group skills by skill type
const groupBySkillType = (skills: Skill[]): Record<string, Skill[]> => {
return skills.reduce((acc: Record<string, Skill[]>, skill) => {
const skillType = skill.skillType || "Other";
if (!acc[skillType]) {
acc[skillType] = [];
}
acc[skillType].push(skill);
return acc;
}, {});
};

const removeDuplicates = (skills: Skill[]): Skill[] => {
const skillSet = new Set();
const uniqueSkills: Skill[] = [];

skills.forEach((skill) => {
const serializedSkill = JSON.stringify(skill);
if (!skillSet.has(serializedSkill)) {
skillSet.add(serializedSkill);
uniqueSkills.push(skill);
}
});

return uniqueSkills;
};

if (groupedBy === "language") {
organizedSkills = skills.reduce((acc: Record<string, Skill[]>, skill) => {
if (skill.technicalGeneralSkills) {
acc[skill.name] = removeDuplicates(skill.technicalGeneralSkills);
const recursiveFilter = (
skills: Skill[],
excludedSkillTypes: ("hard" | "general" | "soft")[],
): Skill[] => {
return skills
.filter((skill) => !excludedSkillTypes.includes(skill.skillType))
.map((skill) => {
const filteredSkill: Skill = { ...skill };

if (filteredSkill.technicalGeneralSkills) {
filteredSkill.technicalGeneralSkills = recursiveFilter(
filteredSkill.technicalGeneralSkills,
excludedSkillTypes,
);
}
return acc;
}, {});
} else if (groupedBy === "category") {
organizedSkills = skills.reduce((acc: Record<string, Skill[]>, skill) => {
const category = skill.category || "Other";
if (!acc[category]) {
acc[category] = [];
if (filteredSkill.technicalHardSkills) {
filteredSkill.technicalHardSkills = recursiveFilter(
filteredSkill.technicalHardSkills,
excludedSkillTypes,
);
}
acc[category].push(skill);
return acc;
}, {});
} else if (groupedBy === "skill-type") {
organizedSkills = skills.reduce((acc: Record<string, Skill[]>, skill) => {
const skillType = skill.skillType || "Other";
if (!acc[skillType]) {
acc[skillType] = [];
if (filteredSkill.technicalSoftSkills) {
filteredSkill.technicalSoftSkills = recursiveFilter(
filteredSkill.technicalSoftSkills,
excludedSkillTypes,
);
}
acc[skillType].push(skill);
return acc;
}, {});
} else {
// groupedBy === "none"
organizedSkills["None"] = removeDuplicates(skills);

return filteredSkill;
});
};

const groupSkills = (
groupedBy: string,
skills: Skill[],
excludedSkillTypes?: ("hard" | "general" | "soft")[], // array of skill types to be excluded
): Record<string, Skill[]> => {
let organizedSkills: Record<string, Skill[]> = {};

// Filter out the skills of excluded types recursively
const filteredSkills = excludedSkillTypes
? recursiveFilter(skills, excludedSkillTypes)
: skills;

switch (groupedBy) {
case "language":
organizedSkills = groupByLanguage(filteredSkills);
break;
case "category":
organizedSkills = groupByCategory(filteredSkills);
break;
case "skill-type":
organizedSkills = groupBySkillType(filteredSkills);
break;
default:
// groupedBy === "none"
organizedSkills["None"] = removeDuplicates(filteredSkills);
break;
}

// Remove duplicates for each category
Expand Down
6 changes: 3 additions & 3 deletions app/blogs/components/BlogList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ export const BlogList: React.FC<BlogListProps> = ({ blogs }) => {
"title",
"subtitle",
"category",
"technicalSkills.skill",
"technicalSkills.name",
"technicalSkills.category",
"technicalSkills.skill.skill",
"softSkills.skill",
"technicalSkills.skill.name",
"softSkills.name",
"softSkills.category",
],
threshold: 0.3,
Expand Down
6 changes: 3 additions & 3 deletions app/credentials/components/CredentialsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ const CredentialsList: React.FC<CredentialsListListProps> = ({
"name",
"issuer",
"category",
"technicalSkills.skill",
"technicalSkills.name",
"technicalSkills.category",
"technicalSkills.skill.skill",
"softSkills.skill",
"technicalSkills.skill.name",
"softSkills.name",
"softSkills.category",
], // Only search these properties
threshold: 0.3, // Lower threshold means more results
Expand Down
10 changes: 5 additions & 5 deletions app/projects/components/ProjectsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ const ProjectsList: React.FC<ProjectsListProps> = ({ allProjects }) => {
const searchOptions = {
keys: [
"name",
"programmingLanguage.skill",
"technologySkills.skill",
"programmingLanguage.name",
"technologySkills.name",
"technologySkills.category",
"technologySkills.skill.skill",
"softSkills.skill",
"technologySkills.skill.name",
"softSkills.name",
"softSkills.category",
"extraTechnicalGeneralSkills.skill",
"extraTechnicalGeneralSkills.name",
"extraTechnicalGeneralSkills.category",
"tags",
],
Expand Down
42 changes: 6 additions & 36 deletions components/Modal/SkillsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Tag from "../Tags/Tag";
import HeadingThree from "../Text/HeadingThree";
import HeadingTwo from "../Text/HeadingTwo";
import { Button } from "../shadcn/ui/button";
import groupSkills from "@/actions/skills/groupSkills";

/**
* Displays a modal for the skills.
Expand All @@ -49,48 +50,17 @@ const SkillsModal: React.FC = () => {
(skill) => skill.isMainSkill,
);

const groupSkills = (
skills: Skill[],
groupedBy: string,
): Record<string, Skill[]> => {
if (groupedBy === "none") {
return { None: skills };
}

return skills.reduce(
(acc, skill) => {
// Group by category
if (groupedBy === "category") {
const key = skill.category;
acc[key] = acc[key] || [];
acc[key].push(skill);
}
// Group by language
else if (
groupedBy === "language" &&
skill.category === "Programming Languages"
) {
skill.technicalGeneralSkills?.forEach((subSkill) => {
if (subSkill.skillType === "hard" && subSkill.isMainSkill) {
const key = skill.name; // Grouping under the main programming language
acc[key] = acc[key] || [];
acc[key].push(subSkill);
}
});
}
return acc;
},
{} as Record<string, Skill[]>,
);
};

const options: FilterOption[] = [
{ slug: "category", entryName: "Category" },
{ slug: "language", entryName: "Language" },
{ slug: "none", entryName: "None" },
];

const groupedSkills = groupSkills(displayedSkills, groupedBy);
const groupedSkills = groupSkills(groupedBy, displayedSkills, [
"general",
"soft",
]);

return (
<Dialog>
<DialogTrigger>
Expand Down