Revert "feat: [tenant] 컨텍스트 메뉴 테넌트 설정 + 콘솔 사이드바 DB 메뉴 적용"
This reverts commit cb254cf138.
This commit is contained in:
@@ -64,18 +64,5 @@ public function boot(): void
|
||||
'favoriteMenuIds' => $menuService->getFavoriteMenuIds(),
|
||||
]);
|
||||
});
|
||||
|
||||
// 테넌트 콘솔 사이드바에 해당 테넌트의 메뉴 데이터 전달
|
||||
View::composer('partials.tenant-console-sidebar', function ($view) {
|
||||
$tenantId = $view->getData()['consoleTenantId'] ?? request()->route('tenantId');
|
||||
if ($tenantId) {
|
||||
$menuService = app(SidebarMenuService::class);
|
||||
$menusBySection = $menuService->getTenantMenusBySection((int) $tenantId);
|
||||
|
||||
$view->with([
|
||||
'tenantMainMenus' => $menusBySection['main'],
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,35 +131,6 @@ public function getMenusBySection(?User $user = null): array
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 테넌트의 전체 메뉴 트리 조회 (권한 필터 없음, 관리 콘솔용)
|
||||
*/
|
||||
public function getTenantMenuTree(int $tenantId): Collection
|
||||
{
|
||||
$allMenus = Menu::withoutGlobalScopes()
|
||||
->where('tenant_id', $tenantId)
|
||||
->where('is_active', true)
|
||||
->where('hidden', false)
|
||||
->orderBy('sort_order')
|
||||
->get();
|
||||
|
||||
return $this->buildMenuTree($allMenus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 테넌트의 섹션별 메뉴 조회 (관리 콘솔용)
|
||||
*/
|
||||
public function getTenantMenusBySection(int $tenantId): array
|
||||
{
|
||||
$menuTree = $this->getTenantMenuTree($tenantId);
|
||||
|
||||
return [
|
||||
'main' => $menuTree->filter(fn ($m) => $m->getSection() === 'main')->values(),
|
||||
'tools' => $menuTree->filter(fn ($m) => $m->getSection() === 'tools')->values(),
|
||||
'labs' => $menuTree->filter(fn ($m) => $m->getSection() === 'labs')->values(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 트리 구성
|
||||
*/
|
||||
|
||||
@@ -121,11 +121,8 @@ class ContextMenu {
|
||||
window.location.href = `/tenants/${id}/edit`;
|
||||
break;
|
||||
case 'switch-tenant':
|
||||
{
|
||||
const w = 1400, h = 900;
|
||||
const l = (screen.width - w) / 2, t = (screen.height - h) / 2;
|
||||
window.open(`/tenant-console/${id}`, `tenant_${id}`,
|
||||
`width=${w},height=${h},left=${l},top=${t},resizable=yes,scrollbars=yes`);
|
||||
if (typeof openTenantConsole === 'function') {
|
||||
openTenantConsole(id, name);
|
||||
}
|
||||
break;
|
||||
case 'view-user':
|
||||
|
||||
@@ -28,12 +28,11 @@ class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex i
|
||||
<button type="button"
|
||||
data-menu-for="tenant"
|
||||
onclick="handleContextMenuAction('switch-tenant')"
|
||||
class="w-full px-4 py-2 text-left text-sm text-purple-600 hover:bg-gray-100 flex items-center gap-2">
|
||||
class="w-full px-4 py-2 text-left text-sm text-green-600 hover:bg-gray-100 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.573-1.066z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
|
||||
</svg>
|
||||
테넌트 설정
|
||||
이 테넌트로 전환
|
||||
</button>
|
||||
|
||||
{{-- 사용자 관련 메뉴 --}}
|
||||
|
||||
@@ -1,8 +1,51 @@
|
||||
{{-- 테넌트 콘솔 전용 사이드바 (DB 기반 메뉴 시스템) --}}
|
||||
{{-- 테넌트 콘솔 전용 사이드바 (메인 사이드바 스타일 통일) --}}
|
||||
@php
|
||||
$tenantId = $consoleTenantId ?? 0;
|
||||
$currentUrl = request()->url();
|
||||
$baseUrl = "/tenant-console/{$tenantId}";
|
||||
$menus = $tenantMainMenus ?? collect();
|
||||
|
||||
$menuGroups = [
|
||||
[
|
||||
'title' => '권한 관리',
|
||||
'icon' => 'ri-shield-keyhole-line',
|
||||
'items' => [
|
||||
['name' => '권한 관리', 'url' => "{$baseUrl}/permissions", 'icon' => 'ri-key-2-line'],
|
||||
['name' => '역할 관리', 'url' => "{$baseUrl}/roles", 'icon' => 'ri-user-settings-line'],
|
||||
['name' => '역할-권한 매핑', 'url' => "{$baseUrl}/role-permissions", 'icon' => 'ri-links-line'],
|
||||
['name' => '부서-권한 매핑', 'url' => "{$baseUrl}/department-permissions", 'icon' => 'ri-building-2-line'],
|
||||
['name' => '사용자-권한 매핑', 'url' => "{$baseUrl}/user-permissions", 'icon' => 'ri-user-star-line'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => '시스템 관리',
|
||||
'icon' => 'ri-settings-3-line',
|
||||
'items' => [
|
||||
['name' => 'AI 설정', 'url' => "{$baseUrl}/system/ai-config", 'icon' => 'ri-robot-line'],
|
||||
['name' => '휴일 관리', 'url' => "{$baseUrl}/system/holidays", 'icon' => 'ri-calendar-event-line'],
|
||||
['name' => '시스템 알림', 'url' => "{$baseUrl}/system/alerts", 'icon' => 'ri-notification-3-line'],
|
||||
['name' => '공통코드', 'url' => "{$baseUrl}/common-codes", 'icon' => 'ri-code-s-slash-line'],
|
||||
['name' => '카테고리', 'url' => "{$baseUrl}/categories", 'icon' => 'ri-node-tree'],
|
||||
['name' => '감사 로그', 'url' => "{$baseUrl}/audit-logs", 'icon' => 'ri-file-list-3-line'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => '생산관리',
|
||||
'icon' => 'ri-instance-line',
|
||||
'items' => [
|
||||
['name' => '품목관리', 'url' => "{$baseUrl}/production/items", 'icon' => 'ri-box-3-line'],
|
||||
['name' => '품목필드', 'url' => "{$baseUrl}/production/item-fields", 'icon' => 'ri-list-settings-line'],
|
||||
['name' => '견적수식', 'url' => "{$baseUrl}/production/quote-formulas", 'icon' => 'ri-calculator-line'],
|
||||
['name' => '카테고리', 'url' => "{$baseUrl}/production/categories", 'icon' => 'ri-node-tree'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => '게시판관리',
|
||||
'icon' => 'ri-article-line',
|
||||
'items' => [
|
||||
['name' => '게시판 목록', 'url' => "{$baseUrl}/boards", 'icon' => 'ri-layout-grid-line'],
|
||||
],
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
|
||||
<aside class="w-64 bg-white border-r border-gray-200 flex flex-col shrink-0">
|
||||
@@ -17,120 +60,45 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 메뉴 영역 (DB 기반) --}}
|
||||
{{-- 메뉴 영역 --}}
|
||||
<nav class="flex-1 overflow-y-auto p-4">
|
||||
<ul class="space-y-1">
|
||||
@foreach($menus as $menu)
|
||||
@if($menu->menuChildren && $menu->menuChildren->isNotEmpty())
|
||||
{{-- 1depth: 그룹 헤더 --}}
|
||||
@php
|
||||
$groupId = 'tc-menu-group-' . $menu->id;
|
||||
$children = $menu->menuChildren;
|
||||
@endphp
|
||||
<li class="pt-4 pb-1 border-t border-gray-200 mt-2">
|
||||
<button onclick="document.getElementById('{{ $groupId }}').classList.toggle('hidden')"
|
||||
class="w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-700 hover:bg-gray-50 rounded"
|
||||
style="padding-left: 0.75rem">
|
||||
<span class="flex items-center gap-2">
|
||||
@if($menu->icon)
|
||||
<i class="{{ $menu->icon }} w-4 h-4 text-base"></i>
|
||||
@endif
|
||||
{{ $menu->name }}
|
||||
</span>
|
||||
<svg class="w-3 h-3 transition-transform rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
@foreach($menuGroups as $groupIndex => $group)
|
||||
{{-- 1depth: 그룹 헤더 (메인 사이드바 menu-group 스타일) --}}
|
||||
<li class="pt-4 pb-1 border-t border-gray-200 mt-2">
|
||||
<button @click="$refs.group{{ $groupIndex }}.classList.toggle('hidden')"
|
||||
class="w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-700 hover:bg-gray-50 rounded"
|
||||
style="padding-left: 0.75rem">
|
||||
<span class="flex items-center gap-2">
|
||||
<i class="{{ $group['icon'] }} w-4 h-4 text-base"></i>
|
||||
{{ $group['title'] }}
|
||||
</span>
|
||||
<svg class="w-3 h-3 transition-transform rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{{-- 2depth: 메뉴 아이템 --}}
|
||||
<ul id="{{ $groupId }}" class="space-y-1 mt-1">
|
||||
@foreach($children as $child)
|
||||
@if($child->menuChildren && $child->menuChildren->isNotEmpty())
|
||||
{{-- 3depth: 서브그룹 --}}
|
||||
@php
|
||||
$subGroupId = 'tc-menu-group-' . $child->id;
|
||||
$subChildren = $child->menuChildren;
|
||||
@endphp
|
||||
<li>
|
||||
<button onclick="document.getElementById('{{ $subGroupId }}').classList.toggle('hidden')"
|
||||
class="w-full flex items-center justify-between px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg"
|
||||
style="padding-left: 1.5rem">
|
||||
<span class="flex items-center gap-2">
|
||||
@if($child->icon)
|
||||
<i class="{{ $child->icon }} text-base text-gray-400"></i>
|
||||
@endif
|
||||
<span class="font-semibold">{{ $child->name }}</span>
|
||||
</span>
|
||||
<svg class="w-3 h-3 transition-transform rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
<ul id="{{ $subGroupId }}" class="space-y-1 mt-1">
|
||||
@foreach($subChildren as $subChild)
|
||||
@php
|
||||
$subItemUrl = $subChild->url ? $baseUrl . $subChild->url : '#';
|
||||
$isSubActive = $subChild->url && str_ends_with(request()->path(), ltrim($subChild->url, '/'));
|
||||
$subActiveClass = $isSubActive
|
||||
? 'bg-primary text-white hover:bg-primary'
|
||||
: 'text-gray-700 hover:bg-gray-100';
|
||||
@endphp
|
||||
<li>
|
||||
<a href="{{ $subItemUrl }}"
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm {{ $subActiveClass }}"
|
||||
style="padding-left: 2.25rem">
|
||||
@if($subChild->icon)
|
||||
<i class="{{ $subChild->icon }} text-base {{ $isSubActive ? '' : 'text-gray-400' }}"></i>
|
||||
@endif
|
||||
{{ $subChild->name }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</li>
|
||||
@else
|
||||
{{-- 2depth: 단일 메뉴 아이템 --}}
|
||||
@php
|
||||
$itemUrl = $child->url ? $baseUrl . $child->url : '#';
|
||||
$isActive = $child->url && str_ends_with(request()->path(), ltrim($child->url, '/'));
|
||||
$activeClass = $isActive
|
||||
? 'bg-primary text-white hover:bg-primary'
|
||||
: 'text-gray-700 hover:bg-gray-100';
|
||||
@endphp
|
||||
<li>
|
||||
<a href="{{ $itemUrl }}"
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm {{ $activeClass }}"
|
||||
style="padding-left: 1.5rem">
|
||||
@if($child->icon)
|
||||
<i class="{{ $child->icon }} text-base {{ $isActive ? '' : 'text-gray-400' }}"></i>
|
||||
@endif
|
||||
{{ $child->name }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
</ul>
|
||||
</li>
|
||||
@else
|
||||
{{-- 1depth: 단일 메뉴 아이템 (그룹이 아닌 경우) --}}
|
||||
@php
|
||||
$itemUrl = $menu->url ? $baseUrl . $menu->url : '#';
|
||||
$isActive = $menu->url && str_ends_with(request()->path(), ltrim($menu->url, '/'));
|
||||
$activeClass = $isActive
|
||||
? 'bg-primary text-white hover:bg-primary'
|
||||
: 'text-gray-700 hover:bg-gray-100';
|
||||
@endphp
|
||||
<li>
|
||||
<a href="{{ $itemUrl }}"
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm {{ $activeClass }}"
|
||||
style="padding-left: 0.75rem">
|
||||
@if($menu->icon)
|
||||
<i class="{{ $menu->icon }} text-base {{ $isActive ? '' : 'text-gray-400' }}"></i>
|
||||
@endif
|
||||
{{ $menu->name }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
{{-- 2depth: 메뉴 아이템 (메인 사이드바 menu-item 스타일) --}}
|
||||
<ul x-ref="group{{ $groupIndex }}" class="space-y-1 mt-1">
|
||||
@foreach($group['items'] as $item)
|
||||
@php
|
||||
$isActive = str_starts_with($currentUrl, url($item['url']));
|
||||
$activeClass = $isActive
|
||||
? 'bg-primary text-white hover:bg-primary'
|
||||
: 'text-gray-700 hover:bg-gray-100';
|
||||
@endphp
|
||||
<li>
|
||||
<a href="{{ $item['url'] }}"
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm {{ $activeClass }}"
|
||||
style="padding-left: 1.5rem">
|
||||
<i class="{{ $item['icon'] }} text-base {{ $isActive ? '' : 'text-gray-400' }}"></i>
|
||||
{{ $item['name'] }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -142,4 +110,4 @@ class="flex items-center gap-2 text-sm text-gray-500 hover:text-gray-700 transit
|
||||
테넌트 목록으로
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
</aside>
|
||||
|
||||
Reference in New Issue
Block a user