Files
sam-manage/resources/views/permissions/partials/table.blade.php
hskwon c921ef43f9 feat(ui): 사이드바 메뉴 그룹화 및 접기/펼치기 기능 구현
- 메뉴를 4개 그룹으로 재구성 (시스템 관리, 권한 관리, 생산 관리, 시스템)
- 그룹 접기/펼치기 기능 추가 (localStorage 상태 저장)
- 그룹 내 메뉴 인덴트 적용 (2rem)
- 그룹 구분선 및 시각적 계층 구조 강화
- 권한 테이블 레이아웃 최적화 (한 줄 표시)
- 사이드바 메뉴 가이드 문서 작성 (SIDEBAR_MENU_GUIDE.md)

변경 파일:
- resources/views/partials/sidebar.blade.php
- resources/views/permissions/partials/table.blade.php
- SIDEBAR_MENU_GUIDE.md (신규)
2025-11-25 11:53:17 +09:00

196 lines
8.5 KiB
PHP

@php
use App\Models\Commons\Menu;
/**
* 권한명을 파싱하여 메뉴 태그와 권한 타입을 시각적으로 표시
*/
function formatPermissionName(string $permissionName): string
{
// menu:{menu_id}.{permission_type} 패턴 파싱
if (preg_match('/^menu:(\d+)\.(\w+)$/', $permissionName, $matches)) {
$menuId = (int) $matches[1];
$permissionType = $matches[2];
// 메뉴 정보 조회
$menu = Menu::find($menuId);
$menuName = $menu ? $menu->name : '알 수 없는 메뉴';
// 권한 타입별 설정
$permissionConfig = getPermissionConfig($permissionType);
// HTML 생성 (Admin과 동일한 스타일)
$html = '<div class="flex items-center gap-1 flex-nowrap">';
// 메뉴 태그 (회색 배지)
$html .= sprintf(
'<span style="display: inline-flex; align-items: center; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; border-radius: 0.375rem; background-color: rgb(243 244 246); color: rgb(31 41 55);">메뉴 #%d</span>',
$menuId
);
// 메뉴명
$html .= sprintf(
'<span class="text-sm text-gray-700">%s</span>',
htmlspecialchars($menuName)
);
// 권한 타입 배지
$html .= sprintf(
'<span style="display: inline-flex; align-items: center; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 600; border-radius: 0.375rem; %s" title="%s">%s</span>',
$permissionConfig['style'],
$permissionConfig['label'],
$permissionConfig['badge']
);
$html .= '</div>';
return $html;
}
// 패턴이 일치하지 않으면 원본 반환
return '<span class="text-sm text-gray-900">' . htmlspecialchars($permissionName) . '</span>';
}
/**
* 권한 타입별 설정 반환 (Admin과 동일한 색상)
*/
function getPermissionConfig(string $type): array
{
$configs = [
'view' => [
'badge' => 'V',
'label' => '조회',
'style' => 'background-color: rgb(219 234 254); color: rgb(30 64 175);',
],
'create' => [
'badge' => 'C',
'label' => '생성',
'style' => 'background-color: rgb(220 252 231); color: rgb(21 128 61);',
],
'update' => [
'badge' => 'U',
'label' => '수정',
'style' => 'background-color: rgb(254 215 170); color: rgb(154 52 18);',
],
'delete' => [
'badge' => 'D',
'label' => '삭제',
'style' => 'background-color: rgb(254 202 202); color: rgb(153 27 27);',
],
'approve' => [
'badge' => 'A',
'label' => '승인',
'style' => 'background-color: rgb(233 213 255); color: rgb(107 33 168);',
],
'export' => [
'badge' => 'E',
'label' => '내보내기',
'style' => 'background-color: rgb(207 250 254); color: rgb(14 116 144);',
],
'manage' => [
'badge' => 'M',
'label' => '관리',
'style' => 'background-color: rgb(243 244 246); color: rgb(31 41 55);',
],
];
return $configs[$type] ?? [
'badge' => strtoupper(substr($type, 0, 1)),
'label' => $type,
'style' => 'background-color: rgb(243 244 246); color: rgb(31 41 55);',
];
}
@endphp
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">ID</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">권한명</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">테넌트</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">가드</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">할당된 역할</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">할당된 부서</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">생성일</th>
<th class="px-4 py-2 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">수정일</th>
<th class="px-4 py-2 text-right text-sm font-semibold text-gray-700 uppercase tracking-wider">액션</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse($permissions as $permission)
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900">
{{ $permission->id }}
</td>
<td class="px-4 py-3 whitespace-nowrap">
{!! formatPermissionName($permission->name) !!}
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{{ $permission->tenant?->company_name ?? '전역' }}
</td>
<td class="px-4 py-3 whitespace-nowrap">
<span style="display: inline-flex; align-items: center; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; border-radius: 0.375rem; background-color: rgb(219 234 254); color: rgb(30 64 175);">
{{ $permission->guard_name }}
</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900">
@if($permission->roles->isNotEmpty())
<div class="flex flex-nowrap gap-1">
@foreach($permission->roles as $role)
<span style="display: inline-flex; align-items: center; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; border-radius: 0.375rem; background-color: rgb(220 252 231); color: rgb(21 128 61);">
{{ $role->name }}
</span>
@endforeach
</div>
@else
<span class="text-gray-400">-</span>
@endif
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900">
@if($permission->departments->isNotEmpty())
<div class="flex flex-nowrap gap-1">
@foreach($permission->departments as $department)
<span style="display: inline-flex; align-items: center; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; border-radius: 0.375rem; background-color: rgb(254 249 195); color: rgb(133 77 14);">
{{ $department->name }}
</span>
@endforeach
</div>
@else
<span class="text-gray-400">-</span>
@endif
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{{ $permission->created_at?->format('Y-m-d H:i') ?? '-' }}
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
{{ $permission->updated_at?->format('Y-m-d H:i') ?? '-' }}
</td>
<td class="px-4 py-3 whitespace-nowrap text-right text-sm font-medium">
<a href="{{ route('permissions.edit', $permission->id) }}"
class="text-blue-600 hover:text-blue-900 mr-3">
수정
</a>
<button onclick="confirmDelete({{ $permission->id }}, '{{ $permission->name }}')"
class="text-red-600 hover:text-red-900">
삭제
</button>
</td>
</tr>
@empty
<tr>
<td colspan="9" class="px-6 py-12 text-center text-gray-500">
등록된 권한이 없습니다.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- 페이지네이션 -->
@include('partials.pagination', [
'paginator' => $permissions,
'target' => '#permission-table',
'includeForm' => '#filterForm'
])