Skip to content

Commit

Permalink
Merge pull request #1390 from AndyTWF/stand-assignment-context
Browse files Browse the repository at this point in the history
Stand assignment context
  • Loading branch information
AndyTWF authored Sep 13, 2023
2 parents dae836c + beca79b commit 6c775e2
Show file tree
Hide file tree
Showing 32 changed files with 1,393 additions and 142 deletions.
174 changes: 174 additions & 0 deletions app/Filament/Resources/StandAssignmentsHistoryResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<?php

namespace App\Filament\Resources;

use App\Filament\Helpers\SelectOptions;
use App\Filament\Resources\StandAssignmentsHistoryResource\Pages;
use App\Models\Airfield\Airfield;
use App\Models\Stand\Stand;
use App\Models\Stand\StandAssignmentsHistory;
use App\Models\User\RoleKeys;
use App\Policies\ChecksUserRoles;
use Closure;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\ViewField;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;

class StandAssignmentsHistoryResource extends Resource
{
use TranslatesStrings;
use ChecksUserRoles;

protected static ?string $model = StandAssignmentsHistory::class;

protected static ?string $navigationIcon = 'heroicon-o-collection';
protected static ?string $navigationLabel = 'Stand Assignment History';
protected static ?string $label = 'Stand Assignment History';

protected static ?string $navigationGroup = 'Airfield';

public static function getEloquentQuery(): Builder
{
return StandAssignmentsHistory::with('stand', 'stand.airfield');
}

public static function canGloballySearch(): bool
{
return false;
}

protected static function userCanAccess(): bool
{
return self::checkUserHasRole(
auth()->user(),
[
RoleKeys::OPERATIONS_CONTRIBUTOR,
RoleKeys::OPERATIONS_TEAM,
RoleKeys::WEB_TEAM,
RoleKeys::DIVISION_STAFF_GROUP,
]
);
}

protected static function shouldRegisterNavigation(): bool
{
return self::userCanAccess();
}

public function mount(): void
{
dd(self::userCanAccess());
abort_unless(self::userCanAccess(), 403);
}

public static function form(Form $form): Form
{
return $form
->disabled()
->schema([
ViewField::make('context')
->columnSpanFull()
->view('filament.forms.stand_assignment_history_context')
->label(static::translateFormPath('columns.context')),
]);
}

public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('callsign')
->label(static::translateTablePath('columns.callsign'))
->searchable(),
TextColumn::make('identifier')
->getStateUsing(fn (StandAssignmentsHistory $record) => $record->stand->airfieldIdentifier)
->label(static::translateTablePath('columns.identifier'))
->searchable(),
TextColumn::make('assigned_at')
->label(static::translateTablePath('columns.assigned_at'))
->dateTime(),
TextColumn::make('deleted_at')
->placeholder('--')
->label(static::translateTablePath('columns.deleted_at'))
->dateTime(),
TextColumn::make('type')
->label(static::translateTablePath('columns.type')),
])
->actions([
ViewAction::make('view_context')
->label('View Context')
->hidden(
fn (StandAssignmentsHistory $record) => is_null($record->context) || empty($record->context)
),
])
->filters([
Filter::make('callsign')
->formComponent(TextInput::class)
->query(
fn (Builder $query, array $data) => isset($data['isActive'])
? $query->where('callsign', $data['isActive'])
: $query
),
Filter::make('airfield_and_stand')
->form([
Select::make('airfield')
->options(SelectOptions::airfields())
->reactive()
->searchable()
->label('Airfield'),
Select::make('stand')
->options(
fn (Closure $get) => SelectOptions::standsForAirfield(Airfield::find($get('airfield')))
)
->searchable()
->label('Stand')
->hidden(fn (Closure $get) => !$get('airfield')),
])
->indicateUsing(function (array $data) {
if (isset($data['stand'])) {
return 'Stand: ' . Stand::find($data['stand'])->airfieldIdentifier;
}

if (isset($data['airfield'])) {
return 'Airfield: ' . Airfield::find($data['airfield'])->code;
}

return null;
})
->query(function (Builder $query, array $data) {
if (isset($data['airfield'])) {
$query->whereHas(
'stand.airfield',
fn (Builder $query) => $query->where('id', $data['airfield'])
);
}

if (isset($data['stand'])) {
$query->where('stand_id', $data['stand']);
}

return $query;
}),
]);
}

public static function getPages(): array
{
return [
'index' => Pages\ListStandAssignmentsHistories::route('/'),
'view' => Pages\ViewAssignmentContext::route('/{record}'),
];
}

protected static function translationPathRoot(): string
{
return 'stand_assignments_history';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Filament\Resources\StandAssignmentsHistoryResource\Pages;

use App\Filament\Resources\Pages\LimitsTableRecordListingOptions;
use App\Filament\Resources\StandAssignmentsHistoryResource;
use Filament\Resources\Pages\ListRecords;

class ListStandAssignmentsHistories extends ListRecords
{
use LimitsTableRecordListingOptions;

protected static string $resource = StandAssignmentsHistoryResource::class;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\Filament\Resources\StandAssignmentsHistoryResource\Pages;

use App\Filament\Resources\StandAssignmentsHistoryResource;
use Filament\Resources\Pages\ViewRecord;

class ViewAssignmentContext extends ViewRecord
{
protected static string $resource = StandAssignmentsHistoryResource::class;
}
3 changes: 2 additions & 1 deletion app/Http/Controllers/StandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public function createStandAssignment(Request $request): JsonResponse
try {
$this->assignmentsService->createStandAssignment(
$request->json('callsign'),
(int)$request->json('stand_id')
(int)$request->json('stand_id'),
'User'
);
return response()->json([], 201);
} catch (StandNotFoundException) {
Expand Down
13 changes: 12 additions & 1 deletion app/Models/Stand/StandAssignmentsHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ class StandAssignmentsHistory extends Model
protected $fillable = [
'callsign',
'stand_id',
'user_id'
'user_id',
'type',
'context',
];

protected $casts = [
'context' => 'array',
];

public function stand()
{
return $this->belongsTo(Stand::class);
}
}
10 changes: 10 additions & 0 deletions app/Policies/ChecksUserRoles.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@

trait ChecksUserRoles
{
private function userHasAnyRole(User $user): bool
{
return $user->roles()->count() > 0;
}

private function userHasRole(User $user, array $roles): bool
{
return self::checkUserHasRole($user, $roles);
}

private static function checkUserHasRole(User $user, array $roles): bool
{
foreach ($user->roles as $role) {
if ($role->isOneOf($roles)) {
Expand Down
72 changes: 1 addition & 71 deletions app/Policies/ReadOnlyPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Policies;

use App\Models\User\User;
use Illuminate\Auth\Access\HandlesAuthorization;

/**
Expand All @@ -11,6 +10,7 @@
class ReadOnlyPolicy
{
use HandlesAuthorization;
use RejectsNonReadOnlyActions;

public function view(): bool
{
Expand All @@ -21,74 +21,4 @@ public function viewAny(): bool
{
return true;
}

public function attach(): bool
{
return false;
}

public function detach(): bool
{
return false;
}

public function update(): bool
{
return false;
}

public function create(): bool
{
return false;
}

public function delete(): bool
{
return false;
}

public function restore(): bool
{
return false;
}

public function forceDelete(): bool
{
return false;
}

public function detachAny(): bool
{
return false;
}

public function dissociate(): bool
{
return false;
}

public function dissociateAny(): bool
{
return false;
}

public function replicate(): bool
{
return false;
}

public function restoreAny(): bool
{
return false;
}

public function deleteAny(): bool
{
return false;
}

public function forceDeleteAny(): bool
{
return false;
}
}
26 changes: 26 additions & 0 deletions app/Policies/ReadOnlyWithRolePolicy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;
use App\Models\User\User;

/**
* Policy that allows read only access only to users with a role.
*/
class ReadOnlyWithRolePolicy
{
use HandlesAuthorization;
use ChecksUserRoles;
use RejectsNonReadOnlyActions;

public function view(?User $user): bool
{
return $this->userHasAnyRole($user);
}

public function viewAny(?User $user): bool
{
return $this->userHasAnyRole($user);
}
}
Loading

0 comments on commit 6c775e2

Please sign in to comment.