chore: Update branch #4
|
@ -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,64 +127,64 @@ async function fetchSecondarySkills() {
|
|||
secondarySkillSelect.innerHTML = "";
|
||||
secondarySkillSelect.appendChild(createOption("Loading...", true, true));
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/secondary-skill/from-primary-skill?psid=${selectedPrimarySkillId}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorMessage = `Server returned ${response.status}: ${response.statusText}`;
|
||||
throw new Error(errorMessage);
|
||||
// try {
|
||||
const response = await fetch(
|
||||
`/api/secondary-skill/from-primary-skill?psid=${selectedPrimarySkillId}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const responseText = await response.text();
|
||||
console.log("Response Text:", responseText);
|
||||
|
||||
let secondarySkills;
|
||||
try {
|
||||
secondarySkills = JSON.parse(responseText);
|
||||
} catch (jsonError) {
|
||||
throw new Error(`Failed to parse JSON: ${jsonError.message}`);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
);
|
||||
if (!response.ok) {
|
||||
const errorMessage = `Server returned ${response.status}: ${response.statusText}`;
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
const responseText = await response.text();
|
||||
console.log("Response Text:", responseText);
|
||||
|
||||
let secondarySkills;
|
||||
try {
|
||||
secondarySkills = JSON.parse(responseText);
|
||||
} catch (jsonError) {
|
||||
throw new Error(`Failed to parse JSON: ${jsonError.message}`);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//====================================================================================
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
newSkillSelector.querySelector("#secondarySkill").value = "";
|
||||
// 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();
|
||||
|
|
Loading…
Reference in New Issue