authorize('instances.restart'); $instance = Instance::query()->where('uuid', $uuid)->first(); if ($instance === null) { return; } try { $run = app(RestartInstance::class)($instance); } catch (AuthorizationException) { $this->dispatch('notify', message: __('admin.restart_denied')); return; } // Null is every ordinary refusal — no live machine, or a run already in // flight against this order. Said out loud, because an operator who // pressed a button and saw nothing will press it again. $this->dispatch('notify', message: __($run === null ? 'admin.restart_busy' : 'admin.restart_started')); } public function render() { $instances = Instance::query() ->with(['customer', 'host']) ->orderByDesc('id') ->paginate(25); return view('livewire.admin.instances', [ 'instances' => $instances, // Whether to draw the action column at all. An operator who may not // restart anything should not be reading a column of buttons that // answer them 403. 'canRestart' => Gate::allows('instances.restart'), 'rows' => $instances->getCollection()->map(fn (Instance $i) => [ // R11: a row's action is addressed by uuid, never the numeric id. 'uuid' => $i->uuid, // Only a machine remote work can actually reach. A reservation // with no VM, a failed build and an ended service all have // nothing to restart — see Instance::hasLiveMachine(). 'live' => $i->hasLiveMachine(), // The operator list shows what is actually served — an unverified // custom domain is a plan, not an address. 'address' => $i->domainIsVerified() ? $i->custom_domain : $i->subdomain, 'customer' => $i->customer?->name ?? '—', 'host' => $i->host?->name ?? '—', 'vmid' => $i->vmid ?? '—', 'plan' => $i->plan !== null ? __('billing.plan.'.$i->plan) : '—', // The whole allowance, packs included — the same figure the // customer's own page states and the same one Nextcloud is // told. An operator reading the package alone here would be // looking at a smaller number than the machine enforces and // would have no way of telling. 'quota' => ($owed = StorageAllowance::for($i)->totalGb()) > 0 ? $owed.' GB' : '—', // A machine running on less CPU or RAM than it has been sold — // see Instance::restartIsPending(). Shown beside the status // rather than as one, because the instance is genuinely active // and the operator needs both facts at once. 'restart' => $i->restartIsPending(), 'status' => $status = $i->status ?? 'provisioning', // A status the lifecycle adds later must show as itself, never // as "admin.status.whatever" in front of the owner. 'status_label' => Lang::has('admin.status.'.$status) ? __('admin.status.'.$status) : $status, ])->all(), ]); } }