- 사용자 목록에 테넌트 컬럼 추가 (기본 테넌트 인디고 배지) - UserService: tenants 관계 eager loading 추가 - 컨텍스트 메뉴 우클릭 → 좌클릭 변경 (캡처링 방식) - 전체 blade 파일 툴팁 통일: '클릭하여 메뉴 열기' - flow-tester 오류 분석 문구 수정
205 lines
12 KiB
PHP
205 lines
12 KiB
PHP
@php
|
|
$activeTab = request('tab', 'access-allowed');
|
|
@endphp
|
|
|
|
@if(isset($analysis['error']))
|
|
<div class="text-center py-12 text-red-500">
|
|
<svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
</svg>
|
|
<p>{{ $analysis['error'] }}</p>
|
|
</div>
|
|
@else
|
|
<!-- 요약 정보 -->
|
|
<div class="mb-4 p-3 bg-gray-50 rounded-lg">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-4">
|
|
<span class="text-sm text-gray-600">
|
|
전체 사용자: <span class="font-bold text-gray-900">{{ $analysis['summary']['total_users'] ?? 0 }}</span>명
|
|
</span>
|
|
<span class="text-sm text-gray-600">
|
|
접근 가능: <span class="font-bold text-green-600">{{ $analysis['summary']['allowed_count'] ?? 0 }}</span>명
|
|
</span>
|
|
<span class="text-sm text-gray-600">
|
|
명시적 DENY: <span class="font-bold text-red-600">{{ $analysis['summary']['explicit_deny_count'] ?? 0 }}</span>명
|
|
</span>
|
|
</div>
|
|
<span class="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded">
|
|
{{ strtoupper($permissionType) }} 권한
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 접근 가능 탭 콘텐츠 -->
|
|
<div id="tab-access-allowed" class="{{ $activeTab !== 'access-allowed' ? 'hidden' : '' }}">
|
|
@if(count($analysis['access_allowed'] ?? []) > 0)
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-sm">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th class="px-4 py-2 text-left font-medium text-gray-700">사용자</th>
|
|
<th class="px-4 py-2 text-left font-medium text-gray-700">부서</th>
|
|
<th class="px-4 py-2 text-left font-medium text-gray-700">역할</th>
|
|
<th class="px-4 py-2 text-center font-medium text-gray-700">개인 설정</th>
|
|
<th class="px-4 py-2 text-center font-medium text-gray-700">근거</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200">
|
|
@foreach($analysis['access_allowed'] as $user)
|
|
<tr class="hover:bg-gray-50">
|
|
<td class="px-4 py-3">
|
|
<div class="font-medium text-gray-900 cursor-pointer hover:text-blue-600"
|
|
data-context-menu="user"
|
|
data-entity-id="{{ $user['id'] }}"
|
|
data-entity-name="{{ $user['name'] }}"
|
|
title="클릭하여 메뉴 열기">{{ $user['name'] }}</div>
|
|
<div class="text-xs text-gray-500">{{ $user['email'] }}</div>
|
|
</td>
|
|
<td class="px-4 py-3">
|
|
@if(count($user['departments']) > 0)
|
|
@foreach($user['departments'] as $dept)
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-gray-100 text-gray-800 rounded mr-1 mb-1">
|
|
{{ $dept['name'] }}
|
|
@if($dept['is_primary'])
|
|
<span class="ml-1 text-blue-600">*</span>
|
|
@endif
|
|
</span>
|
|
@endforeach
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3">
|
|
@if(count($user['roles']) > 0)
|
|
@foreach($user['roles'] as $role)
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-purple-100 text-purple-800 rounded mr-1 mb-1">
|
|
{{ $role['display_name'] ?? $role['name'] }}
|
|
</span>
|
|
@endforeach
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3 text-center">
|
|
@if($user['personal_override'] === 'allow')
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-green-100 text-green-800 rounded">
|
|
ALLOW
|
|
</span>
|
|
@elseif($user['personal_override'] === 'deny')
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-red-100 text-red-800 rounded">
|
|
DENY
|
|
</span>
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3 text-center">
|
|
@if($user['source'] === 'role')
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-purple-100 text-purple-800 rounded">
|
|
역할
|
|
</span>
|
|
@elseif($user['source'] === 'department')
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-blue-100 text-blue-800 rounded">
|
|
부서
|
|
</span>
|
|
@elseif($user['source'] === 'personal')
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-yellow-100 text-yellow-800 rounded">
|
|
개인
|
|
</span>
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@else
|
|
<div class="text-center py-8 text-gray-500">
|
|
<p>접근 가능한 사용자가 없습니다.</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- 명시적 DENY 탭 콘텐츠 -->
|
|
<div id="tab-explicit-deny" class="{{ $activeTab !== 'explicit-deny' ? 'hidden' : '' }}">
|
|
@if(count($analysis['explicit_deny'] ?? []) > 0)
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-sm">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th class="px-4 py-2 text-left font-medium text-gray-700">사용자</th>
|
|
<th class="px-4 py-2 text-left font-medium text-gray-700">부서</th>
|
|
<th class="px-4 py-2 text-left font-medium text-gray-700">역할</th>
|
|
<th class="px-4 py-2 text-center font-medium text-gray-700">개인 설정</th>
|
|
<th class="px-4 py-2 text-center font-medium text-gray-700">비고</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200">
|
|
@foreach($analysis['explicit_deny'] as $user)
|
|
<tr class="hover:bg-gray-50">
|
|
<td class="px-4 py-3">
|
|
<div class="font-medium text-gray-900 cursor-pointer hover:text-blue-600"
|
|
data-context-menu="user"
|
|
data-entity-id="{{ $user['id'] }}"
|
|
data-entity-name="{{ $user['name'] }}"
|
|
title="클릭하여 메뉴 열기">{{ $user['name'] }}</div>
|
|
<div class="text-xs text-gray-500">{{ $user['email'] }}</div>
|
|
</td>
|
|
<td class="px-4 py-3">
|
|
@if(count($user['departments']) > 0)
|
|
@foreach($user['departments'] as $dept)
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-gray-100 text-gray-800 rounded mr-1 mb-1">
|
|
{{ $dept['name'] }}
|
|
</span>
|
|
@endforeach
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3">
|
|
@if(count($user['roles']) > 0)
|
|
@foreach($user['roles'] as $role)
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-purple-100 text-purple-800 rounded mr-1 mb-1">
|
|
{{ $role['display_name'] ?? $role['name'] }}
|
|
</span>
|
|
@endforeach
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-4 py-3 text-center">
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-red-100 text-red-800 rounded">
|
|
DENY
|
|
</span>
|
|
</td>
|
|
<td class="px-4 py-3 text-center">
|
|
<span class="inline-flex items-center px-2 py-0.5 text-xs font-medium bg-red-100 text-red-800 rounded">
|
|
개인 권한 차단
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@else
|
|
<div class="text-center py-8 text-gray-500">
|
|
<p>명시적 DENY 설정된 사용자가 없습니다.</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
|
|
<script>
|
|
// 현재 탭에 따라 콘텐츠 표시
|
|
document.querySelectorAll('[id^="tab-"]').forEach(tab => {
|
|
tab.classList.add('hidden');
|
|
});
|
|
|
|
const currentTabContent = document.getElementById('tab-' + (typeof currentTab !== 'undefined' ? currentTab : 'access-allowed'));
|
|
if (currentTabContent) {
|
|
currentTabContent.classList.remove('hidden');
|
|
}
|
|
</script> |