159 lines
9.7 KiB
PHP
159 lines
9.7 KiB
PHP
{{-- Permission grid partial. Expects: $model (string), $permissionGroups (array), $allVerbs (array), $isSystem (bool) --}}
|
|
@php $isSystem = $isSystem ?? false; @endphp
|
|
<div class="-mx-6 overflow-x-auto px-6">
|
|
<div style="min-width: calc(140px + {{ count($allVerbs) }} * 72px)">
|
|
@if ($isSystem)
|
|
<div class="mb-2 flex items-center gap-1.5 text-xs text-gray-500">
|
|
<x-icon name="lock-closed" class="h-3.5 w-3.5" />
|
|
{{ __('System role permissions are locked and cannot be modified.') }}
|
|
</div>
|
|
@endif
|
|
@foreach ($permissionGroups as $group)
|
|
@if (!empty($group['section']))
|
|
<div class="mt-3 mb-1 border-t border-gray-200 pt-2">
|
|
<span class="text-xs font-semibold uppercase tracking-wide text-gray-400">{{ __($group['section']) }}</span>
|
|
</div>
|
|
@elseif (!empty($group['inline']))
|
|
@php $inlinePerms = array_values($group['permissions']); $inlineKeys = array_keys($group['permissions']); @endphp
|
|
<div class="grid gap-x-1 rounded hover:bg-gray-50 py-2"
|
|
style="grid-template-columns: 140px repeat({{ count($allVerbs) }}, 72px); align-items: start;">
|
|
<div class="text-xs font-medium text-gray-700 pl-1">{{ __($group['inline']) }}</div>
|
|
@foreach ($allVerbs as $vIndex => $verb)
|
|
<div class="flex justify-center">
|
|
@if (isset($inlineKeys[$vIndex]))
|
|
<label class="flex flex-col items-center gap-0.5 {{ $isSystem ? 'cursor-not-allowed' : 'cursor-pointer' }}">
|
|
<input
|
|
type="checkbox"
|
|
value="{{ $inlineKeys[$vIndex] }}"
|
|
wire:model="{{ $model }}.permissions"
|
|
{{ $isSystem ? 'disabled' : '' }}
|
|
class="rounded border-gray-300 text-theme-brand focus:ring-theme-brand h-3.5 w-3.5 {{ $isSystem ? 'cursor-not-allowed opacity-60' : 'cursor-pointer' }}">
|
|
<span class="text-xs text-gray-500">{{ __($inlinePerms[$vIndex]) }}</span>
|
|
</label>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@elseif (!empty($group['fixed']))
|
|
@foreach ($group['fixed'] as $fixedPermission)
|
|
<div class="grid gap-x-1 rounded hover:bg-gray-50 py-2" style="grid-template-columns: 140px repeat({{ count($allVerbs) }}, 72px); align-items: start;">
|
|
<div class="text-xs font-medium text-gray-700 pl-1 truncate">
|
|
{{ __($fixedPermission) }}
|
|
</div>
|
|
@foreach ($allVerbs as $verb)
|
|
<div class="flex justify-center">
|
|
@if ($loop->last)
|
|
<label class="flex flex-col items-center gap-0.5 {{ $isSystem ? 'cursor-not-allowed' : 'cursor-pointer' }}">
|
|
<input
|
|
type="checkbox"
|
|
value="{{ $fixedPermission }}"
|
|
wire:model="{{ $model }}.permissions"
|
|
{{ $isSystem ? 'disabled' : '' }}
|
|
class="rounded border-gray-300 text-theme-brand focus:ring-theme-brand h-3.5 w-3.5 {{ $isSystem ? 'cursor-not-allowed opacity-60' : 'cursor-pointer' }}">
|
|
<span class="text-xs text-gray-500">{{ __($verb) }}</span>
|
|
</label>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endforeach
|
|
@else
|
|
@php
|
|
$resource = $group['resource'];
|
|
$verbs = $group['verbs'];
|
|
$allPerms = array_map(fn($v) => $v . ' ' . $resource, $verbs);
|
|
$allPermsJs = json_encode($allPerms);
|
|
$manageKey = 'manage ' . $resource;
|
|
$rowLocked = $isSystem && empty($group['unlocked']);
|
|
@endphp
|
|
<div
|
|
class="grid gap-x-1 rounded hover:bg-gray-50 py-2"
|
|
style="grid-template-columns: 140px repeat({{ count($allVerbs) }}, 72px); align-items: start;"
|
|
@if (!$rowLocked)
|
|
x-data="{
|
|
toggleManage(checked, allPerms) {
|
|
let current = [...($wire.get('{{ $model }}.permissions') || [])];
|
|
allPerms.forEach(perm => {
|
|
if (checked) {
|
|
if (!current.includes(perm)) current.push(perm);
|
|
} else {
|
|
current = current.filter(p => p !== perm);
|
|
}
|
|
});
|
|
$wire.set('{{ $model }}.permissions', current);
|
|
},
|
|
uncheckManage(manageKey) {
|
|
let current = [...($wire.get('{{ $model }}.permissions') || [])];
|
|
current = current.filter(p => p !== manageKey);
|
|
$wire.set('{{ $model }}.permissions', current);
|
|
},
|
|
checkView(viewKey) {
|
|
let current = [...($wire.get('{{ $model }}.permissions') || [])];
|
|
if (!current.includes(viewKey)) {
|
|
current.push(viewKey);
|
|
$wire.set('{{ $model }}.permissions', current);
|
|
}
|
|
},
|
|
uncheckAll(allPerms) {
|
|
let current = [...($wire.get('{{ $model }}.permissions') || [])];
|
|
current = current.filter(p => !allPerms.includes(p));
|
|
$wire.set('{{ $model }}.permissions', current);
|
|
}
|
|
}"
|
|
@endif
|
|
>
|
|
<div class="text-xs font-medium text-gray-700 pl-1 truncate">
|
|
{{ __($group['label']) }}
|
|
</div>
|
|
@foreach ($allVerbs as $verb)
|
|
<div class="flex justify-center">
|
|
@if (in_array($verb, $verbs))
|
|
@if ($verb === 'manage')
|
|
<label class="flex flex-col items-center gap-0.5 {{ $rowLocked ? 'cursor-not-allowed' : 'cursor-pointer' }}">
|
|
<input
|
|
type="checkbox"
|
|
value="{{ $manageKey }}"
|
|
wire:model="{{ $model }}.permissions"
|
|
{{ $rowLocked ? 'disabled' : '' }}
|
|
@if (!$rowLocked)
|
|
x-on:change="toggleManage($event.target.checked, {{ $allPermsJs }}); {{ in_array('view', $verbs) ? "if (\$event.target.checked) checkView('view {$resource}')" : '' }}"
|
|
@endif
|
|
class="rounded border-gray-300 text-theme-brand focus:ring-theme-brand h-3.5 w-3.5 {{ $rowLocked ? 'cursor-not-allowed opacity-60' : 'cursor-pointer' }}">
|
|
<span class="text-xs text-gray-500">{{ __($verb) }}</span>
|
|
</label>
|
|
@elseif ($verb === 'view')
|
|
<label class="flex flex-col items-center gap-0.5 {{ $rowLocked ? 'cursor-not-allowed' : 'cursor-pointer' }}">
|
|
<input
|
|
type="checkbox"
|
|
value="view {{ $resource }}"
|
|
wire:model="{{ $model }}.permissions"
|
|
{{ $rowLocked ? 'disabled' : '' }}
|
|
@if (!$rowLocked)
|
|
x-on:change="if (!$event.target.checked) uncheckAll({{ $allPermsJs }})"
|
|
@endif
|
|
class="rounded border-gray-300 text-theme-brand focus:ring-theme-brand h-3.5 w-3.5 {{ $rowLocked ? 'cursor-not-allowed opacity-60' : 'cursor-pointer' }}">
|
|
<span class="text-xs text-gray-500">{{ __($verb) }}</span>
|
|
</label>
|
|
@else
|
|
<label class="flex flex-col items-center gap-0.5 {{ $rowLocked ? 'cursor-not-allowed' : 'cursor-pointer' }}">
|
|
<input
|
|
type="checkbox"
|
|
value="{{ $verb }} {{ $resource }}"
|
|
wire:model="{{ $model }}.permissions"
|
|
{{ $rowLocked ? 'disabled' : '' }}
|
|
@if (!$rowLocked)
|
|
x-on:change="if (!$event.target.checked) uncheckManage('{{ $manageKey }}'); if ($event.target.checked) checkView('view {{ $resource }}')"
|
|
@endif
|
|
class="rounded border-gray-300 text-theme-brand focus:ring-theme-brand h-3.5 w-3.5 {{ $rowLocked ? 'cursor-not-allowed opacity-60' : 'cursor-pointer' }}">
|
|
<span class="text-xs text-gray-500">{{ __($verb) }}</span>
|
|
</label>
|
|
@endif
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
@endforeach
|
|
</div>
|
|
</div>
|