94 lines
3.3 KiB
PHP
94 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\System;
|
|
|
|
use App\Models\Setting;
|
|
use App\Services\DeploymentService;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Attributes\On;
|
|
use Livewire\Component;
|
|
|
|
/**
|
|
* System settings — dashboard-configurable Domain + TLS and the release channel.
|
|
*
|
|
* Domain & TLS: READ-ONLY status. The panel domain is an install-time decision
|
|
* (APP_DOMAIN) so it stays consistent with URL/WebSocket/cookie security; Caddy then
|
|
* issues, renews and HTTP→HTTPS-redirects fully automatically. Nothing to apply or
|
|
* reload here — to change the domain, re-run install.sh.
|
|
*
|
|
* Release-Kanal: a stable|beta choice persisted as a Setting (default from
|
|
* config('clusev.channel')), audited on change.
|
|
*/
|
|
#[Layout('layouts.app')]
|
|
class Index extends Component
|
|
{
|
|
/** Valid user-facing release channels (descriptions are localized at render time). */
|
|
public const CHANNELS = ['stable', 'beta'];
|
|
|
|
/** Channel key => localized description, built per-request for the view. */
|
|
private function channelDescriptions(): array
|
|
{
|
|
return [
|
|
'stable' => __('system.channel_stable'),
|
|
'beta' => __('system.channel_beta'),
|
|
];
|
|
}
|
|
|
|
/** Install-time panel domain (read-only display). */
|
|
public string $domain = '';
|
|
|
|
public string $channel = 'stable';
|
|
|
|
public function mount(DeploymentService $deployment): void
|
|
{
|
|
$this->domain = (string) ($deployment->domain() ?? '');
|
|
$channel = Setting::get('release_channel', config('clusev.channel')) ?? 'stable';
|
|
// Clamp to a valid user channel — a stale/legacy value (e.g. 'dev') falls back to stable.
|
|
$this->channel = in_array($channel, self::CHANNELS, true) ? $channel : 'stable';
|
|
}
|
|
|
|
/** Release channel changes are audited (confirmation via the shared modal). */
|
|
public function confirmChannel(string $channel): void
|
|
{
|
|
if (! in_array($channel, self::CHANNELS, true) || $channel === $this->channel) {
|
|
return;
|
|
}
|
|
|
|
$this->dispatch('openModal',
|
|
component: 'modals.confirm-action',
|
|
arguments: [
|
|
'heading' => __('system.change_channel_heading'),
|
|
'body' => __('system.change_channel_body', ['channel' => $channel]),
|
|
'confirmLabel' => __('system.change_channel_confirm'),
|
|
'danger' => false,
|
|
'icon' => 'git-branch',
|
|
'auditAction' => 'system.settings_updated',
|
|
'auditTarget' => 'release_channel='.$channel,
|
|
'event' => 'channelChanged',
|
|
'params' => ['channel' => $channel],
|
|
'notify' => __('system.change_channel_notify', ['channel' => $channel]),
|
|
],
|
|
);
|
|
}
|
|
|
|
#[On('channelChanged')]
|
|
public function applyChannel(string $channel): void
|
|
{
|
|
if (! in_array($channel, self::CHANNELS, true)) {
|
|
return;
|
|
}
|
|
|
|
Setting::put('release_channel', $channel);
|
|
$this->channel = $channel;
|
|
}
|
|
|
|
public function render(DeploymentService $deployment)
|
|
{
|
|
return view('livewire.system.index', [
|
|
'hasTls' => $this->domain !== '',
|
|
'panelUrl' => $deployment->panelUrl(),
|
|
'channels' => $this->channelDescriptions(),
|
|
])->title(__('system.title'));
|
|
}
|
|
}
|