diff --git a/public/js/menu-sortable.js b/public/js/menu-sortable.js index 0c992873..ffe1f734 100644 --- a/public/js/menu-sortable.js +++ b/public/js/menu-sortable.js @@ -415,6 +415,97 @@ window.moveMenuGroup = function(groupMenuIds, leadId, newParentId, sortOrder, cs }); }; +// ===== 최상위 그룹 상단/하단 이동 ===== + +// 이동 드롭다운 표시 +window.showMoveGroupDropdown = function(menuId, buttonEl) { + // 기존 드롭다운 제거 + const existing = document.getElementById('move-group-dropdown'); + if (existing) { + existing.remove(); + // 같은 버튼 클릭 시 토글 (닫기) + if (existing.dataset.menuId === String(menuId)) return; + } + + const dropdown = document.createElement('div'); + dropdown.id = 'move-group-dropdown'; + dropdown.dataset.menuId = menuId; + dropdown.className = 'move-group-dropdown'; + + dropdown.innerHTML = ` + + + `; + + // 버튼 위치 기준으로 드롭다운 배치 + const rect = buttonEl.getBoundingClientRect(); + dropdown.style.position = 'fixed'; + dropdown.style.left = rect.left + 'px'; + dropdown.style.top = (rect.bottom + 4) + 'px'; + dropdown.style.zIndex = '9999'; + + document.body.appendChild(dropdown); + + // 외부 클릭 시 닫기 + function closeDropdown(e) { + if (!dropdown.contains(e.target) && e.target !== buttonEl && !buttonEl.contains(e.target)) { + dropdown.remove(); + document.removeEventListener('click', closeDropdown, true); + } + } + // 다음 이벤트 루프에서 리스너 등록 (현재 클릭 무시) + setTimeout(() => document.addEventListener('click', closeDropdown, true), 0); +}; + +// 최상위 그룹을 상단/하단으로 이동 +window.moveGroupToPosition = function(menuId, position) { + // 드롭다운 닫기 + const dropdown = document.getElementById('move-group-dropdown'); + if (dropdown) dropdown.remove(); + + // DOM에서 최상위 그룹(depth=0, parent_id="") 수집 + const allRows = document.querySelectorAll('#menu-sortable tr.menu-row[data-depth="0"][data-parent-id=""]'); + if (allRows.length === 0) return; + + const groupIds = Array.from(allRows).map(row => parseInt(row.dataset.menuId)); + const targetIndex = groupIds.indexOf(menuId); + if (targetIndex === -1) return; + + // 이미 해당 위치에 있으면 무시 + if (position === 'top' && targetIndex === 0) return; + if (position === 'bottom' && targetIndex === groupIds.length - 1) return; + + // 대상을 배열에서 제거 후 처음/끝에 삽입 + groupIds.splice(targetIndex, 1); + if (position === 'top') { + groupIds.unshift(menuId); + } else { + groupIds.push(menuId); + } + + // sort_order 계산 (1부터 순차) + const items = groupIds.map((id, index) => ({ + id: id, + sort_order: index + 1 + })); + + // CSRF 토큰 + const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''; + + // 기존 saveMenuOrder API 호출 + window.saveMenuOrder(items, csrfToken); +}; + // 메뉴 순서 저장 API 호출 (같은 레벨) window.saveMenuOrder = function(items, csrfToken) { fetch('/api/admin/menus/reorder', { diff --git a/resources/views/menus/index.blade.php b/resources/views/menus/index.blade.php index 90d21438..a2a2f627 100644 --- a/resources/views/menus/index.blade.php +++ b/resources/views/menus/index.blade.php @@ -314,6 +314,35 @@ class="bg-white rounded-lg shadow-sm overflow-hidden"> 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } } + + /* 최상위 그룹 이동 드롭다운 */ + .move-group-dropdown { + background: white; + border: 1px solid #e5e7eb; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + padding: 4px; + min-width: 150px; + } + .move-group-option { + display: flex; + align-items: center; + gap: 8px; + width: 100%; + padding: 8px 12px; + font-size: 13px; + font-weight: 500; + color: #374151; + border: none; + background: none; + border-radius: 6px; + cursor: pointer; + transition: background-color 0.15s; + } + .move-group-option:hover { + background-color: #eff6ff; + color: #2563eb; + } @endpush diff --git a/resources/views/menus/partials/table.blade.php b/resources/views/menus/partials/table.blade.php index f23fde4f..6ccb9bac 100644 --- a/resources/views/menus/partials/table.blade.php +++ b/resources/views/menus/partials/table.blade.php @@ -65,14 +65,26 @@ class="import-checkbox w-4 h-4 rounded border-gray-300 text-green-600 focus:ring onchange="toggleMenuChildren(this); updateBulkButtonState()" class="menu-checkbox w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"> - {{-- 드래그 핸들 --}} + {{-- 드래그 핸들 + 이동 버튼 --}}