Skip to content

Commit

Permalink
first pass
Browse files Browse the repository at this point in the history
  • Loading branch information
danharrin committed Apr 29, 2024
1 parent 2c22588 commit 389863a
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
@if (filled($activeManager) && isset($managers[$activeManager]))
<div
@if (count($managers) > 1)
id="relationManager{{ ucfirst($activeManager) }}"
role="tabpanel"
tabindex="0"
@endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@ public function mountCanAuthorizeResourceAccess(): void
public static function authorizeResourceAccess(): void
{
abort_unless(static::getResource()::canAccess(), 403);

if ($parentResource = static::getParentResource()) {
abort_unless($parentResource::canAccess(), 403);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Filament\Resources\Pages\Concerns;

use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Livewire\Attributes\Locked;

trait InteractsWithParentRecord
{
#[Locked]
public ?Model $parentRecord = null;

public function mountInteractsWithParentRecord(): void
{
$parentResourceRegistration = static::getResource()::getParentResourceRegistration();

if (! $parentResourceRegistration) {
return;
}

$this->parentRecord = $this->resolveParentRecord(
request()->route()->parameter(
$parentResourceRegistration->getParentRouteParameterName(),
),
);

$this->authorizeParentRecordAccess();
}

protected function authorizeParentRecordAccess(): void
{
abort_unless(static::getParentResource()::canView($this->getParentRecord()), 403);
}

protected function resolveParentRecord(int | string $key): Model
{
$record = static::getParentResource()::resolveRecordRouteBinding($key);

if ($record === null) {
throw (new ModelNotFoundException())->setModel($this->getModel(), [$key]);
}

return $record;
}

public function getParentRecord(): ?Model
{
return $this->parentRecord;
}

public function getParentRecordTitle(): string | Htmlable | null
{
$resource = static::getParentResource();

if (! $resource::hasRecordTitle()) {
return $resource::getTitleCaseModelLabel();
}

return $resource::getRecordTitle($this->getParentRecord());
}

public static function getParentResource(): ?string
{
return static::getResource()::getParentResourceRegistration()?->getParentResource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,19 @@ public function getRecordTitle(): string | Htmlable
*/
public function getBreadcrumbs(): array
{
$resource = static::getResource();

$breadcrumbs = [
$resource::getUrl() => $resource::getBreadcrumb(),
];
$breadcrumbs = parent::getBreadcrumbs();

$resource = static::getResource();
$record = $this->getRecord();

if ($record->exists && $resource::hasRecordTitle()) {
if ($resource::hasPage('view') && $resource::canView($record)) {
$breadcrumbs[
$resource::getUrl('view', ['record' => $record])
$this->getResourceUrl('view')
] = $this->getRecordTitle();
} elseif ($resource::hasPage('edit') && $resource::canEdit($record)) {
$breadcrumbs[
$resource::getUrl('edit', ['record' => $record])
$this->getResourceUrl('edit')
] = $this->getRecordTitle();
} else {
$breadcrumbs[] = $this->getRecordTitle();
Expand All @@ -74,10 +71,6 @@ public function getBreadcrumbs(): array

$breadcrumbs[] = $this->getBreadcrumb();

if (filled($cluster = static::getCluster())) {
return $cluster::unshiftClusterBreadcrumbs($breadcrumbs);
}

return $breadcrumbs;
}

Expand Down
17 changes: 13 additions & 4 deletions packages/panels/src/Resources/Pages/CreateRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ protected function handleRecordCreation(array $data): Model
return $this->associateRecordWithTenant($record, $tenant);
}

if ($parentRecord = $this->getParentRecord()) {
return $this->associateRecordWithParent($record, $parentRecord);
}

$record->save();

return $record;
Expand All @@ -191,6 +195,11 @@ protected function associateRecordWithTenant(Model $record, Model $tenant): Mode
return $relationship->save($record);
}

protected function associateRecordWithParent(Model $record, Model $parent): Model
{
return static::getResource()::getParentResourceRegistration()->getRelationship($parent)->save($record);
}

/**
* @param array<string, mixed> $data
* @return array<string, mixed>
Expand Down Expand Up @@ -238,7 +247,7 @@ protected function getCancelFormAction(): Action
{
return Action::make('cancel')
->label(__('filament-panels::resources/pages/create-record.form.actions.cancel.label'))
->alpineClickHandler('document.referrer ? window.history.back() : (window.location.href = ' . Js::from($this->previousUrl ?? static::getResource()::getUrl()) . ')')
->alpineClickHandler('document.referrer ? window.history.back() : (window.location.href = ' . Js::from($this->previousUrl ?? $this->getResourceUrl()) . ')')
->color('gray');
}

Expand Down Expand Up @@ -280,14 +289,14 @@ protected function getRedirectUrl(): string
$resource = static::getResource();

if ($resource::hasPage('view') && $resource::canView($this->getRecord())) {
return $resource::getUrl('view', ['record' => $this->getRecord(), ...$this->getRedirectUrlParameters()]);
return $this->getResourceUrl('view', $this->getRedirectUrlParameters());
}

if ($resource::hasPage('edit') && $resource::canEdit($this->getRecord())) {
return $resource::getUrl('edit', ['record' => $this->getRecord(), ...$this->getRedirectUrlParameters()]);
return $this->getResourceUrl('edit', $this->getRedirectUrlParameters());
}

return $resource::getUrl('index');
return $this->getResourceUrl();
}

/**
Expand Down
8 changes: 4 additions & 4 deletions packages/panels/src/Resources/Pages/EditRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ protected function configureViewAction(ViewAction $action): void
->form(fn (Schema $form): Schema => static::getResource()::form($form));

if ($resource::hasPage('view')) {
$action->url(fn (): string => static::getResource()::getUrl('view', ['record' => $this->getRecord()]));
$action->url(fn (): string => $this->getResourceUrl('view'));
}
}

Expand All @@ -294,7 +294,7 @@ protected function configureForceDeleteAction(ForceDeleteAction $action): void

$action
->authorize($resource::canForceDelete($this->getRecord()))
->successRedirectUrl($resource::getUrl('index'));
->successRedirectUrl($this->getResourceUrl());
}

protected function configureReplicateAction(ReplicateAction $action): void
Expand All @@ -315,7 +315,7 @@ protected function configureDeleteAction(DeleteAction $action): void

$action
->authorize($resource::canDelete($this->getRecord()))
->successRedirectUrl($resource::getUrl('index'));
->successRedirectUrl($this->getResourceUrl());
}

public function getTitle(): string | Htmlable
Expand Down Expand Up @@ -357,7 +357,7 @@ protected function getCancelFormAction(): Action
{
return Action::make('cancel')
->label(__('filament-panels::resources/pages/edit-record.form.actions.cancel.label'))
->alpineClickHandler('document.referrer ? window.history.back() : (window.location.href = ' . Js::from($this->previousUrl ?? static::getResource()::getUrl()) . ')')
->alpineClickHandler('document.referrer ? window.history.back() : (window.location.href = ' . Js::from($this->previousUrl ?? $this->getResourceUrl()) . ')')
->color('gray');
}

Expand Down
8 changes: 4 additions & 4 deletions packages/panels/src/Resources/Pages/ListRecords.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ protected function configureCreateAction(CreateAction $action): void
}

if ($resource::hasPage('create')) {
$action->url(fn (): string => $resource::getUrl('create'));
$action->url(fn (): string => $this->getResourceUrl('create'));
}
}

Expand Down Expand Up @@ -164,7 +164,7 @@ protected function configureEditAction(EditAction $action): void
->icon(FilamentIcon::resolve('actions::edit-action') ?? 'heroicon-m-pencil-square');

if ($resource::hasPage('edit')) {
$action->url(fn (Model $record): string => $resource::getUrl('edit', ['record' => $record]));
$action->url(fn (Model $record): string => $this->getResourceUrl('edit', ['record' => $record]));
}
}

Expand Down Expand Up @@ -199,7 +199,7 @@ protected function configureViewAction(ViewAction $action): void
->schema(fn (Schema $schema): Schema => $this->infolist($this->form($schema->columns(2))));

if ($resource::hasPage('view')) {
$action->url(fn (Model $record): string => $resource::getUrl('view', ['record' => $record]));
$action->url(fn (Model $record): string => $this->getResourceUrl('view', ['record' => $record]));
}
}

Expand Down Expand Up @@ -321,7 +321,7 @@ protected function makeTable(): Table
continue;
}

return $resource::getUrl($action, ['record' => $record]);
return $this->getResourceUrl($action, ['record' => $record]);
}

return null;
Expand Down
8 changes: 2 additions & 6 deletions packages/panels/src/Resources/Pages/ManageRecords.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@

class ManageRecords extends ListRecords
{
public function getBreadcrumbs(): array
public function hasResourceBreadcrumbs(): bool
{
if (filled($cluster = static::getCluster())) {
return $cluster::unshiftClusterBreadcrumbs([]);
}

return [];
return false;
}
}
77 changes: 71 additions & 6 deletions packages/panels/src/Resources/Pages/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,38 @@
use Filament\Pages\SubNavigationPosition;
use Filament\Panel;
use Filament\Resources\Pages\Concerns\CanAuthorizeResourceAccess;
use Filament\Resources\Pages\Concerns\InteractsWithParentRecord;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Route as RouteFacade;

abstract class Page extends BasePage
{
use CanAuthorizeResourceAccess;
use InteractsWithParentRecord;

protected static ?string $breadcrumb = null;

protected static string $resource;

protected static bool $isDiscovered = false;

/**
* @param array<string, mixed> $parameters
*/
public function getResourceUrl(?string $name = null, array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null): string
{
if (method_exists($this, 'getRecord')) {
$parameters['record'] ??= $this->getRecord();
}

if ($parentResourceRegistration = static::getResource()::getParentResourceRegistration()) {
$parameters[$parentResourceRegistration->getParentRouteParameterName()] ??= $this->getParentRecord();
}

return static::getResource()::getUrl($name, $parameters, $isAbsolute, $panel, $tenant);
}

public static function getRouteName(?string $panel = null): string
{
$routeBaseName = static::getResource()::getRouteBaseName(panel: $panel);
Expand Down Expand Up @@ -112,17 +130,64 @@ public function getBreadcrumb(): ?string
return static::$breadcrumb ?? static::getTitle();
}

public function hasResourceBreadcrumbs(): bool
{
return true;
}

/**
* @return array<string>
*/
public function getBreadcrumbs(): array
{
$resource = static::getResource();

$breadcrumbs = [
$resource::getUrl() => $resource::getBreadcrumb(),
...(filled($breadcrumb = $this->getBreadcrumb()) ? [$breadcrumb] : []),
];
$breadcrumbs = [];

if ($this->hasResourceBreadcrumbs()) {
$resource = static::getResource();

$breadcrumbs[$this->getResourceUrl()] = $resource::getBreadcrumb();

$parentResourceRegistration = $resource::getParentResourceRegistration();
$parentResource = $parentResourceRegistration?->getParentResource();
$parentRecord = $this->getParentRecord();

while ($parentResourceRegistration && $parentRecord) {
$parentRecordTitle = $parentResource::hasRecordTitle() ?
$parentResource::getRecordTitle($parentRecord) :
$parentResource::getTitleCaseModelLabel();

if ($parentResource::hasPage('view') && $parentResource::canView($parentRecord)) {
$breadcrumbs = [
$parentResource::getUrl('view', ['record' => $parentRecord]) => $parentRecordTitle,
...$breadcrumbs,
];
} elseif ($parentResource::hasPage('edit') && $parentResource::canEdit($parentRecord)) {
$breadcrumbs = [
$parentResource::getUrl('edit', ['record' => $parentRecord]) => $parentRecordTitle,
...$breadcrumbs,
];
} else {
$breadcrumbs = [
$parentRecordTitle,
...$breadcrumbs,
];
}

$breadcrumbs = [
$parentResource::getUrl(null, [
'record' => $parentRecord,
]) => $parentResource::getBreadcrumb(),
...$breadcrumbs,
];

$parentResourceRegistration = $parentResource::getParentResourceRegistration();

if ($parentResourceRegistration) {
$parentResource = $parentResourceRegistration->getParentResource();
$parentRecord = $parentRecord->{$parentResourceRegistration->getInverseRelationshipName()};
}
}
}

if (filled($cluster = static::getCluster())) {
return $cluster::unshiftClusterBreadcrumbs($breadcrumbs);
Expand Down
6 changes: 3 additions & 3 deletions packages/panels/src/Resources/Pages/ViewRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ protected function configureEditAction(EditAction $action): void
->form(fn (Schema $form): Schema => static::getResource()::form($form));

if ($resource::hasPage('edit')) {
$action->url(fn (): string => static::getResource()::getUrl('edit', ['record' => $this->getRecord()]));
$action->url(fn (): string => $this->getResourceUrl('edit'));
}
}

Expand All @@ -152,7 +152,7 @@ protected function configureForceDeleteAction(ForceDeleteAction $action): void

$action
->authorize($resource::canForceDelete($this->getRecord()))
->successRedirectUrl($resource::getUrl('index'));
->successRedirectUrl($this->getResourceUrl());
}

protected function configureReplicateAction(ReplicateAction $action): void
Expand All @@ -173,7 +173,7 @@ protected function configureDeleteAction(DeleteAction $action): void

$action
->authorize($resource::canDelete($this->getRecord()))
->successRedirectUrl($resource::getUrl('index'));
->successRedirectUrl($this->getResourceUrl());
}

public function getTitle(): string | Htmlable
Expand Down
Loading

0 comments on commit 389863a

Please sign in to comment.