*/ public array $data = []; /** * @return array */ protected function getHeaderActions(): array { return [ Action::make('save') ->label('Save') ->action(function (): void { $this->save(); }) ->disabled(fn (): bool => ! $this->currentUserCanManage()) ->tooltip(fn (): ?string => $this->currentUserCanManage() ? null : 'You do not have permission to manage workspace settings.'), Action::make('reset') ->label('Reset to default') ->color('danger') ->requiresConfirmation() ->action(function (): void { $this->resetSetting(); }) ->disabled(fn (): bool => ! $this->currentUserCanManage()) ->tooltip(fn (): ?string => $this->currentUserCanManage() ? null : 'You do not have permission to manage workspace settings.'), ]; } public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration { return ActionSurfaceDeclaration::forPage(ActionSurfaceProfile::ListOnlyReadOnly) ->satisfy(ActionSurfaceSlot::ListHeader, 'Header actions provide save and reset controls for the settings form.') ->exempt(ActionSurfaceSlot::InspectAffordance, 'Workspace settings are edited as a singleton form without a record inspect action.') ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'The page does not render table rows with secondary actions.') ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'The page has no bulk actions because it manages a single settings scope.') ->exempt(ActionSurfaceSlot::ListEmptyState, 'The settings form is always rendered and has no list empty state.'); } public function mount(): void { $user = auth()->user(); if (! $user instanceof User) { abort(403); } $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); if ($workspaceId === null) { $this->redirect('/admin/choose-workspace'); return; } $workspace = Workspace::query()->whereKey($workspaceId)->first(); if (! $workspace instanceof Workspace) { abort(404); } $this->workspace = $workspace; $this->authorizeWorkspaceView($user); $this->loadFormState(); } public function content(Schema $schema): Schema { return $schema ->statePath('data') ->schema([ Section::make('Backup settings') ->description('Workspace defaults used when a schedule has no explicit value.') ->schema([ TextInput::make('backup_retention_keep_last_default') ->label('Default retention keep-last') ->numeric() ->integer() ->minValue(1) ->required() ->disabled(fn (): bool => ! $this->currentUserCanManage()) ->helperText('Fallback value for backup schedule retention when retention_keep_last is empty.'), ]), ]); } public function save(): void { $user = auth()->user(); if (! $user instanceof User) { abort(403); } $this->authorizeWorkspaceManage($user); try { app(SettingsWriter::class)->updateWorkspaceSetting( actor: $user, workspace: $this->workspace, domain: 'backup', key: 'retention_keep_last_default', value: $this->data['backup_retention_keep_last_default'] ?? null, ); } catch (ValidationException $exception) { $errors = $exception->errors(); if (isset($errors['value'])) { throw ValidationException::withMessages([ 'data.backup_retention_keep_last_default' => $errors['value'], ]); } throw $exception; } $this->loadFormState(); Notification::make() ->title('Workspace settings saved') ->success() ->send(); } public function resetSetting(): void { $user = auth()->user(); if (! $user instanceof User) { abort(403); } $this->authorizeWorkspaceManage($user); app(SettingsWriter::class)->resetWorkspaceSetting( actor: $user, workspace: $this->workspace, domain: 'backup', key: 'retention_keep_last_default', ); $this->loadFormState(); Notification::make() ->title('Workspace setting reset to default') ->success() ->send(); } private function loadFormState(): void { $resolvedValue = app(SettingsResolver::class)->resolveValue( workspace: $this->workspace, domain: 'backup', key: 'retention_keep_last_default', ); $this->data = [ 'backup_retention_keep_last_default' => is_numeric($resolvedValue) ? (int) $resolvedValue : 30, ]; } private function currentUserCanManage(): bool { $user = auth()->user(); if (! $user instanceof User || ! $this->workspace instanceof Workspace) { return false; } /** @var WorkspaceCapabilityResolver $resolver */ $resolver = app(WorkspaceCapabilityResolver::class); return $resolver->isMember($user, $this->workspace) && $resolver->can($user, $this->workspace, Capabilities::WORKSPACE_SETTINGS_MANAGE); } private function authorizeWorkspaceView(User $user): void { /** @var WorkspaceCapabilityResolver $resolver */ $resolver = app(WorkspaceCapabilityResolver::class); if (! $resolver->isMember($user, $this->workspace)) { abort(404); } if (! $resolver->can($user, $this->workspace, Capabilities::WORKSPACE_SETTINGS_VIEW)) { abort(403); } } private function authorizeWorkspaceManage(User $user): void { /** @var WorkspaceCapabilityResolver $resolver */ $resolver = app(WorkspaceCapabilityResolver::class); if (! $resolver->isMember($user, $this->workspace)) { abort(404); } if (! $resolver->can($user, $this->workspace, Capabilities::WORKSPACE_SETTINGS_MANAGE)) { abort(403); } } }