chore: Update branch #4

Merged
2021323 merged 3 commits from :main into main 2024-11-15 02:19:57 +01:00
2 changed files with 208 additions and 88 deletions

View File

@ -77,16 +77,12 @@ function updateSecondarySkillsDropdown(secondarySkills, selectElement) {
}
selectElement.appendChild(
createOption("Select a secondary skill", true, true)
createOption("Bitte eine Fähigkeit auswählen", true, true)
);
secondarySkills.forEach((skill) => {
selectElement.appendChild(
createOption(skill.description, false, false, skill.ssid)
);
});
selectElement.disabled = false;
initSkillSelector(secondarySkills);
}
/**
@ -107,6 +103,15 @@ function initializeSkillsDropdowns() {
async function fetchSecondarySkills() {
const primarySkillSelect = document.getElementById("primarySkill");
// If there is more than one selector delete all except the first one
const skillSelectors = document.querySelectorAll(".skill-selector");
if (skillSelectors.length > 1) {
for (let i = 1; i < skillSelectors.length; i++) {
skillSelectors[i].remove();
}
}
const secondarySkillSelect = document.getElementById("secondarySkill");
const selectedPrimarySkillId = primarySkillSelect.value;
@ -122,7 +127,7 @@ async function fetchSecondarySkills() {
secondarySkillSelect.innerHTML = "";
secondarySkillSelect.appendChild(createOption("Loading...", true, true));
try {
// try {
const response = await fetch(
`/api/secondary-skill/from-primary-skill?psid=${selectedPrimarySkillId}`,
{
@ -150,36 +155,36 @@ async function fetchSecondarySkills() {
}
updateSecondarySkillsDropdown(secondarySkills, secondarySkillSelect);
} catch (error) {
console.error("Error fetching secondary skills:", error);
secondarySkillSelect.innerHTML = "";
secondarySkillSelect.appendChild(
createOption("Error loading secondary skills", true, true)
);
secondarySkillSelect.disabled = true;
// } catch (error) {
// console.error("Error fetching secondary skills:", error);
// secondarySkillSelect.innerHTML = "";
// secondarySkillSelect.appendChild(
// createOption("Error loading secondary skills", true, true)
// );
// secondarySkillSelect.disabled = true;
let userMessage = "";
if (error.name === "TypeError" && !window.navigator.onLine) {
userMessage =
"No internet connection. Please check your network and try again.";
} else if (error.message.includes("Server returned 404")) {
userMessage =
"The selected primary skill was not found. Please refresh and try again.";
} else if (error.message.includes("Server returned 500")) {
userMessage = "Server error occurred. Please try again in a few minutes.";
} else if (error.message.includes("Server returned 403")) {
userMessage =
"You don't have permission to access these skills. Please contact support.";
} else {
userMessage = `Failed to load secondary skills: ${error.message}`;
}
showTemporaryMessage(
userMessage,
"error",
5000,
secondarySkillSelect.parentNode
);
}
// let userMessage = "";
// if (error.name === "TypeError" && !window.navigator.onLine) {
// userMessage =
// "No internet connection. Please check your network and try again.";
// } else if (error.message.includes("Server returned 404")) {
// userMessage =
// "The selected primary skill was not found. Please refresh and try again.";
// } else if (error.message.includes("Server returned 500")) {
// userMessage = "Server error occurred. Please try again in a few minutes.";
// } else if (error.message.includes("Server returned 403")) {
// userMessage =
// "You don't have permission to access these skills. Please contact support.";
// } else {
// userMessage = `Failed to load secondary skills: ${error.message}`;
// }
// showTemporaryMessage(
// userMessage,
// "error",
// 5000,
// secondarySkillSelect.parentNode
// );
// }
}
document.addEventListener("DOMContentLoaded", initializeSkillsDropdowns);

View File

@ -1,31 +1,129 @@
function handleSecondarySkillSelection(selectElement) {
const skillCreator = document.querySelector("#skillCreator");
const newSkillSelector = selectElement.closest(".row").cloneNode(true);
const selectedOptions = Array.from(
document.querySelectorAll("#skillCreator select[name='ssid']")
).map((select) => select.value);
/**
* Creates an option element for a select dropdown
*/
var secondarySkillsList = {};
// Filter out already selected options
const secondarySkillSelect =
newSkillSelector.querySelector("#secondarySkill");
const options = Array.from(secondarySkillSelect.options);
options.forEach((option) => {
if (selectedOptions.includes(option.value)) {
option.remove();
//====================================================================================
/**
* Initializes the skill selector with the available secondary skills
* @param {SecondarySkill[]} secondarySkills - Array of secondary skills from the API
*/
function initSkillSelector(secondarySkills) {
secondarySkillsList = secondarySkills;
rebuildOptions();
}
//====================================================================================
/**
* Populates the secondary skills dropdowns with the available options
* and updates the options based on the selected values in the other dropdowns
*/
function rebuildOptions() {
// Get all secondary skill dropdowns
const secondarySkillSelects = document.querySelectorAll("#secondarySkill");
// Make a list with all options that are currently selected
const selectedOptions = [];
secondarySkillSelects.forEach((select) => {
selectedOptions.push(select.value);
});
// Make a list with all options that are not selected
const availableOptions = [];
secondarySkillsList.forEach((skill) => {
if (!selectedOptions.includes(skill.ssid.toString())) {
availableOptions.push(skill);
}
});
// Check if there are any options left to select
if (secondarySkillSelect.options.length <= 1) {
return; // Exit if no options left
// Iterate over all secondary skill dropdowns
secondarySkillSelects.forEach((select) => {
// Save the current selected value
const selectedValue = select.value;
const selectedElement = select.querySelector(
`option[value="${selectedValue}"]`
);
// Clear the dropdown
select.innerHTML = "";
// Add selectedElement back to the dropdown
select.appendChild(selectedElement);
// Add all other options
availableOptions.forEach((skill) => {
select.appendChild(
createOption(skill.description, false, false, skill.ssid)
);
});
});
}
newSkillSelector.querySelector("#secondarySkill").value = "";
//====================================================================================
/**
* Handles the selection of a secondary skill in a dropdown
* @param {HTMLSelectElement} selectElement - The secondary skill dropdown
*/
function handleSecondarySkillSelection(selectElement) {
const skillCreator = document.querySelector("#skillCreator");
const skillSelectors = document.querySelectorAll(".skill-selector");
// Check if all existing selectors have an option selected
const allSelected = Array.from(skillSelectors).every((selector) => {
const secondarySkillSelect = selector.querySelector("#secondarySkill");
return secondarySkillSelect.value;
});
// Test if we can have more selectors
if (!allSelected || skillSelectors.length >= secondarySkillsList.length) {
rebuildOptions();
updateRemoveButtonsVisibility();
return;
}
// Add a new skill selector
addSkillSelector(selectElement);
}
//====================================================================================
/*
* Creates an option element for a select dropdown
*/
function addSkillSelector() {
// Clone the first skill selector
const newSkillSelector = document
.querySelector(".skill-selector")
.cloneNode(true);
// Clear the selected value and set the default level
newSkillSelector.querySelector("#level").value = "1";
newSkillSelector.querySelector(".btn-default").disabled = true;
newSkillSelector.querySelector(".btn-default").style.display = "none";
// Clear the secondary skill dropdown and set it to the default value
const secondarySkillSelect =
newSkillSelector.querySelector("#secondarySkill");
secondarySkillSelect.innerHTML = "";
secondarySkillSelect.appendChild(
createOption("Bitte eine Fähigkeit auswählen", true, true)
);
const skillSelectorList = document.querySelector("#skillSelectorList");
skillSelectorList.appendChild(newSkillSelector);
// Delete the existing options and set it to the default value
rebuildOptions();
// Add event listener to the new "Entfernen" button
newSkillSelector
.querySelector(".btn-default")
.addEventListener("click", function (event) {
event.preventDefault();
handleRemoveSkillButtonClick(this);
});
// Append the new skill selector to the container
skillSelectorList.appendChild(newSkillSelector);
// Initialize star rating components for the new skill selector
initializeStarRatingComponents();
@ -33,21 +131,21 @@ function handleSecondarySkillSelection(selectElement) {
updateRemoveButtonsVisibility();
}
//====================================================================================
/**
* Updates the visibility of the "Entfernen" buttons based on the number of skill selectors
*/
function updateRemoveButtonsVisibility() {
const skillSelectors = document.querySelectorAll(".skill-selector");
const removeButtons = document.querySelectorAll(".btn-default");
// Show "Entfernen" buttons only if there are at least two skill selectors
if (skillSelectors.length > 1) {
removeButtons.forEach((button) => {
const selectElement = button
.closest(".skill-selector")
.querySelector("#secondarySkill");
if (selectElement.value) {
button.style.display = "inline-block";
} else {
button.style.display = "none";
}
?.querySelector("#secondarySkill");
button.style.display =
selectElement && selectElement.value ? "inline-block" : "none";
});
} else {
removeButtons.forEach((button) => {
@ -56,12 +154,29 @@ function updateRemoveButtonsVisibility() {
}
}
//====================================================================================
/**
* Handles the removal of a skill selector
* @param {HTMLButtonElement} button - The "Entfernen" button that was clicked
*/
function handleRemoveSkillButtonClick(button) {
const skillSelector = button.closest(".skill-selector");
skillSelector.remove();
updateRemoveButtonsVisibility();
// If there is no slector with an empty value left we need to add one
if (
document.querySelectorAll("#secondarySkill option[value='']").length === 0
) {
addSkillSelector();
} else {
rebuildOptions();
}
}
//====================================================================================
/**
* Creates an option element for a select dropdown
*/
document.addEventListener("DOMContentLoaded", function () {
// Initialize star rating components on page load
initializeStarRatingComponents();