diff --git a/app/Livewire/Security/ApiTokens.php b/app/Livewire/Security/ApiTokens.php index 0ffd0a6ce7..7798203cb4 100644 --- a/app/Livewire/Security/ApiTokens.php +++ b/app/Livewire/Security/ApiTokens.php @@ -166,8 +166,10 @@ class ApiTokens extends Component 'expires_at' => $expiresAt?->toIso8601String(), ]); $this->getTokens(); + $this->form->reset(); + $this->form->scopeMode = $this->canUseTeamScope ? 'team' : 'selected'; // Do NOT strip the numeric prefix (e.g. "69|...") — Sanctum uses it to index and look up tokens. - session()->flash('token', $token->plainTextToken); + $this->dispatch('api-token-issued', token: $token->plainTextToken); } catch (\Exception $e) { return handleError($e, $this); } @@ -330,7 +332,7 @@ class ApiTokens extends Component 'api_token_name' => $token->name, ]); $this->getTokens(); - session()->flash('token', $plainTextToken); + $this->dispatch('api-token-issued', token: $plainTextToken); } catch (\Exception $e) { return handleError($e, $this); } diff --git a/resources/views/components/forms/listbox.blade.php b/resources/views/components/forms/listbox.blade.php index a9e5533050..3c36204bf0 100644 --- a/resources/views/components/forms/listbox.blade.php +++ b/resources/views/components/forms/listbox.blade.php @@ -24,6 +24,7 @@ 'searchPlaceholder' => 'Search…', 'searchEmptyText' => 'No matching options', 'allowCustom' => false, // true (with searchable) = the search text can be chosen as a custom value + 'countLabel' => null, // with multiple: always show a count such as "3 resources" instead of the selected labels ]) @php @@ -49,8 +50,10 @@ $selectedLabels = collect($options) ->filter(fn ($option) => empty($option['header']) && in_array((string) $option['value'], $selectedValues, true)) ->pluck('label'); + $countLabels = $countLabel ? [$countLabel, Illuminate\Support\Str::plural($countLabel)] : null; $multipleLabel = match (true) { $selectedLabels->isEmpty() => $placeholder, + $countLabels !== null => $selectedLabels->count().' '.$countLabels[$selectedLabels->count() === 1 ? 0 : 1], $selectedLabels->count() <= 2 => $selectedLabels->implode(', '), default => $selectedLabels->count().' selected', }; @@ -138,6 +141,9 @@ get current() { const labels = this.selectedLabels; if (labels.length === 0) return @js($placeholder); + @if ($countLabels) + return `${labels.length} ${labels.length === 1 ? @js($countLabels[0]) : @js($countLabels[1])}`; + @endif return labels.length <= 2 ? labels.join(', ') : `${labels.length} selected`; }, get title() { diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php index fc1bd291bc..1034c28083 100644 --- a/resources/views/components/navbar.blade.php +++ b/resources/views/components/navbar.blade.php @@ -154,10 +154,10 @@ ]], ['label' => 'Keys & Tokens', 'icon' => 'keys', 'children' => [ ['label' => 'Private Keys', 'icon' => 'keys', 'href' => route('security.private-key.index'), 'active' => request()->is('security/private-key*'), 'visible' => $teamWide], - ['label' => 'Cloud Tokens', 'icon' => 'cloud', 'href' => route('security.cloud-tokens'), 'active' => request()->is('security/cloud-tokens*'), 'visible' => $teamWide && auth()->user()?->can('viewAny', App\Models\CloudProviderToken::class)], - ['label' => 'Integration Tokens', 'icon' => 'network', 'href' => route('security.integration-tokens'), 'active' => request()->is('security/integration-tokens'), 'visible' => $teamWide && auth()->user()?->can('viewAny', App\Models\IntegrationToken::class)], - ['label' => 'Cloud-Init Scripts', 'icon' => 'file-content', 'href' => route('security.cloud-init-scripts'), 'active' => request()->is('security/cloud-init-scripts*'), 'visible' => $teamWide && auth()->user()?->can('viewAny', App\Models\CloudInitScript::class)], ['label' => 'API Tokens', 'icon' => 'code', 'href' => route('security.api-tokens'), 'active' => request()->is('security/api-tokens')], + ['label' => 'Cloud Tokens', 'icon' => 'cloud', 'href' => route('security.cloud-tokens'), 'active' => request()->is('security/cloud-tokens*'), 'sectionStart' => true, 'visible' => $teamWide && auth()->user()?->can('viewAny', App\Models\CloudProviderToken::class)], + ['label' => 'Integration Tokens', 'icon' => 'network', 'href' => route('security.integration-tokens'), 'active' => request()->is('security/integration-tokens'), 'visible' => $teamWide && auth()->user()?->can('viewAny', App\Models\IntegrationToken::class)], + ['label' => 'Cloud-Init Scripts', 'icon' => 'file-content', 'href' => route('security.cloud-init-scripts'), 'active' => request()->is('security/cloud-init-scripts*'), 'sectionStart' => true, 'visible' => $teamWide && auth()->user()?->can('viewAny', App\Models\CloudInitScript::class)], ]], ['label' => 'Subscription', 'icon' => 'subscription', 'href' => isCloud() ? route('subscription.show') : '', 'active' => request()->is('subscription*'), 'visible' => $teamWide && isCloud() && auth()->user()->isAdmin()], ['label' => 'Tags', 'icon' => 'tags', 'href' => route('tags.show'), 'active' => request()->is('tags*', 'canvas/tags'), 'visible' => $teamWide], diff --git a/resources/views/components/security/settings-layout.blade.php b/resources/views/components/security/settings-layout.blade.php index 3985e6b413..819628d038 100644 --- a/resources/views/components/security/settings-layout.blade.php +++ b/resources/views/components/security/settings-layout.blade.php @@ -6,6 +6,12 @@ 'active' => request()->routeIs('security.private-key.*'), 'icon' => 'keys', ], + [ + 'label' => 'API Tokens', + 'route' => 'security.api-tokens', + 'active' => request()->routeIs('security.api-tokens'), + 'icon' => 'code', + ], auth()->user()?->can('viewAny', App\Models\CloudProviderToken::class) ? [ 'label' => 'Cloud Tokens', 'route' => 'security.cloud-tokens', @@ -24,12 +30,6 @@ 'active' => request()->routeIs('security.cloud-init-scripts*'), 'icon' => 'file-content', ] : null, - [ - 'label' => 'API Tokens', - 'route' => 'security.api-tokens', - 'active' => request()->routeIs('security.api-tokens'), - 'icon' => 'code', - ], ])->filter(); @endphp diff --git a/resources/views/livewire/security/api-tokens.blade.php b/resources/views/livewire/security/api-tokens.blade.php index 8491ae5c34..5cac1c1a58 100644 --- a/resources/views/livewire/security/api-tokens.blade.php +++ b/resources/views/livewire/security/api-tokens.blade.php @@ -1,5 +1,7 @@ +{{-- The new token value lives only in Alpine, so a Livewire update can not hide it or close its modal. --}}
- This value will not be shown again after you leave this page. -
-+ Copy the token now. It is not shown again after you close this window. +
+