`;
}
/**
* Build group HTML for order editor
* @param {Array} enabledSections - Enabled sections to render in reorderable list
* @param {Array} disabledSections - Disabled sections to render in non-reorderable list
* @param {Object} options - Options object
*/
function buildGroupHTMLForEditor(enabledSections, disabledSections = [], options = {}) {
const { showUpDownButtons = false } = options;
const sortedEnabled = [...(enabledSections || [])].sort((a, b) => (a.order || 0) - (b.order || 0));
const sortedDisabled = [...(disabledSections || [])].sort((a, b) => (a.order || 0) - (b.order || 0));
let html = '';
// Enabled sections list (reorderable)
if (sortedEnabled.length > 0) {
html += `
${sortedEnabled.map((section, index) =>
buildSectionRowHTMLForEditor(section, {
showUpDownButtons,
isFirst: index === 0,
isLast: index === sortedEnabled.length - 1
})
).join('')}
`;
}
// Disabled sections list (non-reorderable)
// Buttons are always rendered, CSS hides them for disabled sections
if (sortedDisabled.length > 0) {
html += `
Disabled Sections
${sortedDisabled.map((section) =>
buildSectionRowHTMLForEditor(section, {
showUpDownButtons: showUpDownButtons, // Use same setting as enabled sections
isFirst: false,
isLast: false
})
).join('')}
`;
}
return html;
}
/**
* Calculate new order with enhanced logic for same-order sections
*/
function calculateNewOrderEnhanced(draggedElement, targetElement, dropPosition, getSectionOrder) {
const container = targetElement.parentElement;
const allRows = Array.from(container.querySelectorAll('.section-row'));
// Find the target's position in the DOM
const targetIndex = allRows.indexOf(targetElement);
const draggedIndex = allRows.indexOf(draggedElement);
if (dropPosition === 'above') {
// Dropped above target element
if (targetIndex === 0) {
// Dropped at the beginning - use first section order - 1
const firstSectionId = targetElement.dataset.sectionId;
const firstOrder = getSectionOrder(firstSectionId);
return Math.max(0, firstOrder - 1);
} else {
// Get preceding and following sections
const precedingElement = allRows[targetIndex - 1];
const followingElement = targetElement;
if (precedingElement && followingElement) {
const precedingId = precedingElement.dataset.sectionId;
const followingId = followingElement.dataset.sectionId;
const precedingOrder = getSectionOrder(precedingId);
const followingOrder = getSectionOrder(followingId);
// If same order, use that order
if (precedingOrder === followingOrder) {
return precedingOrder;
}
}
// Different orders or missing - use target's order - 1
const targetSectionId = targetElement.dataset.sectionId;
const targetOrder = getSectionOrder(targetSectionId);
return Math.max(0, targetOrder - 1);
}
} else {
// dropPosition === 'below'
if (targetIndex === allRows.length - 1) {
// Dropped at the end - use last section order + 1
const lastSectionId = targetElement.dataset.sectionId;
const lastOrder = getSectionOrder(lastSectionId);
return lastOrder + 1;
} else {
// Get preceding and following sections
const precedingElement = targetElement;
const followingElement = allRows[targetIndex + 1];
if (precedingElement && followingElement && followingElement !== draggedElement) {
const precedingId = precedingElement.dataset.sectionId;
const followingId = followingElement.dataset.sectionId;
const precedingOrder = getSectionOrder(precedingId);
const followingOrder = getSectionOrder(followingId);
// If same order, use that order
if (precedingOrder === followingOrder) {
return precedingOrder;
}
}
// Different orders or missing - use following section order - 1, or preceding + 1
if (followingElement && followingElement !== draggedElement) {
const nextSectionId = followingElement.dataset.sectionId;
const nextOrder = getSectionOrder(nextSectionId);
return Math.max(0, nextOrder - 1);
} else {
const targetSectionId = targetElement.dataset.sectionId;
const targetOrder = getSectionOrder(targetSectionId);
return targetOrder + 1;
}
}
}
}
/**
* Render home sections order editor
* @param {Array} sections - Array of section objects
* @param {Object} options - Options object
* @param {boolean} options.showUpDownButtons - Show up/down buttons on hover
* @param {Function} options.onOrderChange - Callback when order changes (sectionId, newOrder)
* @param {Function} options.onToggleChange - Callback when toggle changes (sectionId, enabled)
* @param {Function} options.getSectionOrder - Function to get current order of a section
* @returns {string} HTML string
*/
function renderHomeSectionsOrderEditor(sections, options = {}) {
if (!sections || !Array.isArray(sections)) {
return '