makeSyncAction()]; } protected function getTableEmptyStateActions(): array { return [$this->makeSyncAction()]; } private function makeSyncAction(): Actions\Action { return UiEnforcement::forAction( Actions\Action::make('sync') ->label('Sync from Intune') ->icon('heroicon-o-arrow-path') ->color('primary') ->requiresConfirmation() ->modalHeading('Sync policies from Intune') ->modalDescription('This queues a background sync operation for supported policy types in the current tenant.') ->action(function (self $livewire): void { $tenant = Tenant::current(); $user = auth()->user(); if (! $user instanceof User || ! $tenant instanceof Tenant) { abort(404); } $requestedTypes = array_map( static fn (array $typeConfig): string => (string) $typeConfig['type'], config('tenantpilot.supported_policy_types', []) ); sort($requestedTypes); /** @var OperationRunService $opService */ $opService = app(OperationRunService::class); $opRun = $opService->ensureRun( tenant: $tenant, type: 'policy.sync', inputs: [ 'scope' => 'all', 'types' => $requestedTypes, ], initiator: $user ); if (! $opRun->wasRecentlyCreated && in_array($opRun->status, ['queued', 'running'], true)) { OpsUxBrowserEvents::dispatchRunEnqueued($livewire); OperationUxPresenter::alreadyQueuedToast((string) $opRun->type) ->actions([ Actions\Action::make('view_run') ->label('View run') ->url(OperationRunLinks::view($opRun, $tenant)), ]) ->send(); return; } $opService->dispatchOrFail($opRun, function () use ($tenant, $requestedTypes, $opRun): void { SyncPoliciesJob::dispatch((int) $tenant->getKey(), $requestedTypes, null, $opRun); }); OpsUxBrowserEvents::dispatchRunEnqueued($livewire); OperationUxPresenter::queuedToast((string) $opRun->type) ->actions([ Actions\Action::make('view_run') ->label('View run') ->url(OperationRunLinks::view($opRun, $tenant)), ]) ->send(); }) ) ->requireCapability(Capabilities::TENANT_SYNC) ->tooltip('You do not have permission to sync policies.') ->apply(); } }