Add Title Permission

master
sundayenglish 4 weeks ago
parent 2046b234d1
commit 61b5596eb7
  1. 130
      app/Components/Permission/Manager.php
  2. 15
      resources/views/components/permission/manager.blade.php
  3. 10
      resources/views/layouts/app.blade.php

@ -10,17 +10,43 @@ use Spatie\Permission\Models\Permission;
class Manager extends Component class Manager extends Component
{ {
use WithPagination; use WithPagination;
/**
* Number of items per page for pagination.
*/
public int $perPage = 10; public int $perPage = 10;
/**
* Pagination theme (bootstrap or tailwind).
*/
protected string $paginationTheme = 'bootstrap'; protected string $paginationTheme = 'bootstrap';
public string $mode = 'index'; // 'index' hoặc 'form' /**
public ?int $editingId = null; // id đang edit * Current UI mode: 'index' (list view) or 'form' (create/edit view).
public string $search = ''; // search query */
public string $name = ''; // dùng cho form public string $mode = 'index';
/**
* ID of the permission currently being edited.
* Null when creating a new permission.
*/
public ?int $editingId = null;
/**
* Current search query string.
*/
public string $search = '';
// Khi sự kiện 'permissionSaved' được dispatch, gọi showIndex() /**
* Permission name used in the create/edit form.
*/
public string $name = '';
/**
* Handle internal Livewire event to switch back to the index (list) view.
*/
#[On('permissionSaved')] #[On('permissionSaved')]
public function showIndex() public function showIndex(): void
{ {
$this->mode = 'index'; $this->mode = 'index';
$this->resetPage(); $this->resetPage();
@ -28,14 +54,24 @@ class Manager extends Component
$this->editingId = null; $this->editingId = null;
} }
// Khi $search đã được cập nhật, reset pagination về trang 1 /**
public function updatedSearch($value) * Reset pagination whenever the search term changes.
*
* @param string $value
* @return void
*/
public function updatedSearch(string $value): void
{ {
$this->resetPage(); $this->resetPage();
} }
// Chuyển sang form (create/edit) /**
public function showForm(int $id = null) * Switch to the form view for creating or editing a permission.
*
* @param int|null $id Permission ID to edit, or null to create new.
* @return void
*/
public function showForm(?int $id = null): void
{ {
$this->mode = 'form'; $this->mode = 'form';
$this->editingId = $id; $this->editingId = $id;
@ -44,42 +80,88 @@ class Manager extends Component
: ''; : '';
} }
// Xóa /**
public function delete(int $id) * Delete a permission by its ID.
*
* @param int $id
* @return void
*/
public function delete(int $id): void
{ {
Permission::findOrFail($id)->delete(); Permission::findOrFail($id)->delete();
session()->flash('message', 'Permission deleted.'); session()->flash('message', 'Permission deleted.');
$this->resetPage(); $this->resetPage();
} }
// Lưu form /**
public function save() * Validate and save the permission (create or update).
*
* @return void
*/
public function save(): void
{ {
$rules = [ $uniqueRule = 'unique:permissions,name'
'name' => 'required|string|unique:permissions,name' . ($this->editingId ? ',' . $this->editingId : '');
. ($this->editingId ? ",{$this->editingId}" : '')
];
$this->validate($rules); $this->validate([
'name' => "required|string|{$uniqueRule}",
]);
Permission::updateOrCreate( Permission::updateOrCreate(
['id' => $this->editingId], ['id' => $this->editingId],
['name' => $this->name] ['name' => $this->name]
); );
session()->flash('message', 'Permission saved.'); session()->flash('message', 'Permission saved.');
// Gọi sự kiện nội bộ Livewire 3 // Trigger internal Livewire event to return to the list view
$this->dispatch('permissionSaved'); $this->dispatch('permissionSaved');
} }
// Render view /**
* Compute dynamic browser title based on current mode and editing state.
*
* @return string
*/
protected function computeTitle(): string
{
if ($this->mode === 'index') {
return 'Permissions';
}
if ($this->mode === 'form' && $this->editingId) {
return "Edit Permission: {$this->name}";
}
return 'Create Permission';
}
/**
* Expose computed title as a Livewire property.
*
* @return string
*/
public function getTitleProperty(): string
{
return $this->computeTitle();
}
/**
* Render the component view with paginated permissions and dynamic title.
*
* @return \Illuminate\View\View
*/
public function render() public function render()
{ {
$permissions = Permission::where('name', 'like', "%{$this->search}%") $permissions = Permission::query()
->when($this->search, fn($q) => $q->where('name', 'like', "%{$this->search}%"))
->orderByDesc('id') ->orderByDesc('id')
->paginate($this->perPage); ->paginate($this->perPage);
return view('components.permission.manager', compact('permissions')); return view('components.permission.manager', [
'permissions' => $permissions,
// Blade can now access {{ $title }} via the computed property
'title' => $this->title,
]);
} }
} }

@ -3,7 +3,8 @@
<div class="card mb-4"> <div class="card mb-4">
{{-- Header --}} {{-- Header --}}
<div class="card-header d-flex justify-content-between align-items-center pb-0"> <div class="card-header d-flex justify-content-between align-items-center pb-0">
<h6 class="mb-0">Permissions</h6> {{-- Tiêu đề động --}}
<h6 class="mb-0">{{ $title }}</h6>
@if ($mode === 'index') @if ($mode === 'index')
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@ -66,14 +67,14 @@
</table> </table>
</div> </div>
{{-- Phân trang chỉ khi >1 trang --}} {{-- Phân trang --}}
<div class="mt-3"> <div class="mt-3">
@if ($permissions->lastPage() > 1) @if ($permissions->lastPage() > 1)
{{ $permissions->links() }} {{ $permissions->links() }}
@endif @endif
</div> </div>
@else @else
{{-- Form (không lồng thêm card) --}} {{-- Form --}}
<h6 class="mb-3">{{ $editingId ? 'Edit Permission' : 'Create Permission' }}</h6> <h6 class="mb-3">{{ $editingId ? 'Edit Permission' : 'Create Permission' }}</h6>
<form wire:submit.prevent="save"> <form wire:submit.prevent="save">
<div class="mb-3"> <div class="mb-3">
@ -94,8 +95,14 @@
</div> </div>
</form> </form>
@endif @endif
</div> </div>
</div> </div>
</div> </div>
{{-- Livewire sẽ chèn và chạy block này sau mỗi lần component render xong --}}
@script
<script>
document.title = @json($title);
</script>
@endscript
</div> </div>

@ -1,11 +1,12 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ $title ?? 'Admin Page' }}</title> <title>{{ $title ?? 'Laravel' }}</title>
{{-- Favicons --}} {{-- Favicons --}}
<link rel="apple-touch-icon" sizes="76x76" href="{{ asset('soft-ui/assets/img/apple-icon.png') }}"> <link rel="apple-touch-icon" sizes="76x76" href="{{ asset('soft-ui/assets/img/apple-icon.png') }}">
@ -64,8 +65,13 @@
{{-- Livewire Scripts --}} {{-- Livewire Scripts --}}
@livewireScripts @livewireScripts
<script>
window.addEventListener('set-title', event => {
document.title = event.detail.title;
});
</script>
{{-- Page-specific JS --}} {{-- Page-specific JS --}}
@stack('scripts') @stack('scripts')
</body> </body>
</html> </html>

Loading…
Cancel
Save