mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-24 15:42:09 +08:00
Merge branch '4.x' into pr/17180
This commit is contained in:
@@ -552,6 +552,24 @@ public function panel(Panel $panel): Panel
|
||||
}
|
||||
```
|
||||
|
||||
### Replacing the sidebar and topbar Livewire components
|
||||
|
||||
You may completely replace the Livewire components that are used to render the sidebar and topbar, passing your own Livewire component class name into the `sidebarLivewireComponent()` or `topbarLivewireComponent()` method:
|
||||
|
||||
```php
|
||||
use App\Livewire\Sidebar;
|
||||
use App\Livewire\Topbar;
|
||||
use Filament\Panel;
|
||||
|
||||
public function panel(Panel $panel): Panel
|
||||
{
|
||||
return $panel
|
||||
// ...
|
||||
->sidebarLivewireComponent(Sidebar::class)
|
||||
->topbarLivewireComponent(Topbar::class);
|
||||
}
|
||||
```
|
||||
|
||||
## Disabling breadcrumbs
|
||||
|
||||
The default layout will show breadcrumbs to indicate the location of the current page within the hierarchy of the app.
|
||||
|
||||
@@ -10,7 +10,7 @@ return [
|
||||
|
||||
'login' => [
|
||||
'before' => 'یا',
|
||||
'label' => 'وارد حساب خود شوید.',
|
||||
'label' => 'ورود به حساب کاربری',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
@if ($hasTopbar)
|
||||
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_BEFORE, scopes: $renderHookScopes) }}
|
||||
|
||||
@livewire(\Filament\Livewire\Topbar::class)
|
||||
@livewire(filament()->getTopbarLivewireComponent())
|
||||
|
||||
{{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\View\PanelsRenderHook::TOPBAR_AFTER, scopes: $renderHookScopes) }}
|
||||
@endif
|
||||
|
||||
@@ -73,7 +73,7 @@ class Register extends SimplePage
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = $this->wrapInDatabaseTransaction(function () {
|
||||
$user = $this->wrapInDatabaseTransaction(function (): Model {
|
||||
$this->callHook('beforeValidate');
|
||||
|
||||
$data = $this->form->getState();
|
||||
|
||||
@@ -26,6 +26,7 @@ use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
use Livewire\Component;
|
||||
|
||||
/**
|
||||
* @method static bool arePasswordsRevealable()
|
||||
@@ -105,6 +106,7 @@ use Illuminate\Support\Facades\Facade;
|
||||
* @method static string | null getTenantProfileUrl(array<string, mixed> $parameters = [])
|
||||
* @method static string | null getTenantRegistrationUrl(array<string, mixed> $parameters = [])
|
||||
* @method static Theme getTheme()
|
||||
* @method static class-string<Component> getTopbarLivewireComponent()
|
||||
* @method static ThemeMode getDefaultThemeMode()
|
||||
* @method static string | null getUserAvatarUrl(Model | Authenticatable $user)
|
||||
* @method static Model | null getUserDefaultTenant(HasTenants | Model | Authenticatable $user)
|
||||
|
||||
@@ -34,6 +34,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Livewire\Component;
|
||||
|
||||
class FilamentManager
|
||||
{
|
||||
@@ -488,11 +489,22 @@ class FilamentManager
|
||||
return $this->getCurrentOrDefaultPanel()->getProfilePage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string<Component>
|
||||
*/
|
||||
public function getSidebarLivewireComponent(): string
|
||||
{
|
||||
return $this->getCurrentOrDefaultPanel()->getSidebarLivewireComponent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string<Component>
|
||||
*/
|
||||
public function getTopbarLivewireComponent(): string
|
||||
{
|
||||
return $this->getCurrentOrDefaultPanel()->getTopbarLivewireComponent();
|
||||
}
|
||||
|
||||
public function getTenantProfilePage(): ?string
|
||||
{
|
||||
return $this->getCurrentOrDefaultPanel()->getTenantProfilePage();
|
||||
|
||||
@@ -8,7 +8,6 @@ use Filament\Clusters\Cluster;
|
||||
use Filament\Livewire\GlobalSearch;
|
||||
use Filament\Livewire\Notifications;
|
||||
use Filament\Livewire\SimpleUserMenu;
|
||||
use Filament\Livewire\Topbar;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Resources\Pages\Page as ResourcePage;
|
||||
use Filament\Resources\RelationManagers\RelationGroup;
|
||||
@@ -492,7 +491,7 @@ trait HasComponents
|
||||
$this->queueLivewireComponentForRegistration(Notifications::class);
|
||||
$this->queueLivewireComponentForRegistration($this->getSidebarLivewireComponent());
|
||||
$this->queueLivewireComponentForRegistration(SimpleUserMenu::class);
|
||||
$this->queueLivewireComponentForRegistration(Topbar::class);
|
||||
$this->queueLivewireComponentForRegistration($this->getTopbarLivewireComponent());
|
||||
|
||||
if ($this->hasEmailVerification() && is_subclass_of($emailVerificationPromptRouteAction = $this->getEmailVerificationPromptRouteAction(), Component::class)) {
|
||||
$this->queueLivewireComponentForRegistration($emailVerificationPromptRouteAction);
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
namespace Filament\Panel\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Filament\Livewire\Topbar;
|
||||
use Livewire\Component;
|
||||
|
||||
trait HasTopbar
|
||||
{
|
||||
protected bool | Closure $hasTopbar = true;
|
||||
|
||||
protected string | Closure | null $topbarLivewireComponent = null;
|
||||
|
||||
public function topbar(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->hasTopbar = $condition;
|
||||
@@ -15,8 +19,26 @@ trait HasTopbar
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<Component> | Closure | null $component
|
||||
*/
|
||||
public function topbarLivewireComponent(string | Closure | null $component): static
|
||||
{
|
||||
$this->topbarLivewireComponent = $component;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasTopbar(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->hasTopbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string<Component>
|
||||
*/
|
||||
public function getTopbarLivewireComponent(): string
|
||||
{
|
||||
return $this->evaluate($this->topbarLivewireComponent) ?? Topbar::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,6 +387,18 @@ public function table(Table $table): Table
|
||||
}
|
||||
```
|
||||
|
||||
You can pass a `direction` parameter as `desc` to reorder the records in descending order instead of ascending:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->reorderable('sort', direction: 'desc');
|
||||
}
|
||||
```
|
||||
|
||||
### Enabling pagination while reordering
|
||||
|
||||
Pagination will be disabled in reorder mode to allow you to move records between pages. It is generally a bad experience to have pagination while reordering, but if would like to override this use `$table->paginatedWhileReordering()`:
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Filament\Tables\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
trait CanReorderRecords
|
||||
@@ -45,6 +46,7 @@ trait CanReorderRecords
|
||||
->update([
|
||||
$orderColumn => new Expression(
|
||||
'case ' . collect($order)
|
||||
->when($this->getTable()->getReorderDirection() === 'desc', fn (Collection $order) => $order->reverse()->values())
|
||||
->map(fn ($recordKey, int $recordIndex): string => 'when ' . $wrappedModelKeyName . ' = ' . DB::getPdo()->quote($recordKey) . ' then ' . ($recordIndex + 1))
|
||||
->implode(' ') . ' end'
|
||||
),
|
||||
|
||||
@@ -74,7 +74,7 @@ trait CanSortRecords
|
||||
}
|
||||
|
||||
if ($this->isTableReordering()) {
|
||||
return $query->orderBy($this->getTable()->getReorderColumn());
|
||||
return $query->orderBy($this->getTable()->getReorderColumn(), $this->getTable()->getReorderDirection());
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@@ -19,6 +19,8 @@ trait CanReorderRecords
|
||||
|
||||
protected string | Closure | null $reorderColumn = null;
|
||||
|
||||
protected string | Closure | null $reorderDirection = null;
|
||||
|
||||
protected ?Closure $modifyReorderRecordsTriggerActionUsing = null;
|
||||
|
||||
public function reorderRecordsTriggerAction(?Closure $callback): static
|
||||
@@ -28,7 +30,7 @@ trait CanReorderRecords
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function reorderable(string | Closure | null $column = null, bool | Closure | null $condition = null): static
|
||||
public function reorderable(string | Closure | null $column = null, bool | Closure | null $condition = null, string | Closure | null $direction = null): static
|
||||
{
|
||||
$this->reorderColumn = $column;
|
||||
|
||||
@@ -36,6 +38,8 @@ trait CanReorderRecords
|
||||
$this->isReorderable = $condition;
|
||||
}
|
||||
|
||||
$this->reorderDirection = $direction;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -72,6 +76,11 @@ trait CanReorderRecords
|
||||
return $this->evaluate($this->reorderColumn);
|
||||
}
|
||||
|
||||
public function getReorderDirection(): string
|
||||
{
|
||||
return $this->evaluate($this->reorderDirection) ?? 'asc';
|
||||
}
|
||||
|
||||
public function isReorderable(): bool
|
||||
{
|
||||
return filled($this->getReorderColumn()) && $this->evaluate($this->isReorderable) && $this->isReorderAuthorized();
|
||||
|
||||
Reference in New Issue
Block a user