feat(shell): point Help entry at the online docs (docs.clusev.com)

The sidebar "Help" item, the command-palette entry and the `g h` shortcut now
open the public documentation site in a new tab instead of the in-panel help
page — no duplicated docs to keep in sync.

- config/clusev.php: add `docs_url` (env CLUSEV_DOCS_URL, default
  https://docs.clusev.com) so the docs host is configurable per install.
- sidebar + command-palette: Help href -> config('clusev.docs_url'),
  target=_blank rel=noopener.
- app.js: navigate() opens absolute http(s) URLs via
  window.open(_, '_blank', 'noopener'); go() resolves leader keys absent from
  CMDK_GO via the (config-driven) nav list, so `g h` follows the docs URL.

The in-panel /help route/component is kept (unlinked) as an offline fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat/v1-foundation
boban 2026-07-02 21:12:29 +02:00
parent 9f784ce97a
commit f3c5fee839
4 changed files with 18 additions and 4 deletions

View File

@ -19,6 +19,11 @@ return [
// is the fallback so a domain set during install still gets automatic TLS.
'domain' => env('APP_DOMAIN'),
// Public documentation site. The dashboard's "Hilfe" entry (sidebar + command palette +
// the `g h` shortcut) opens this instead of duplicating docs in-panel. Canonical for every
// install; env-overridable for a private/mirrored docs host.
'docs_url' => env('CLUSEV_DOCS_URL', 'https://docs.clusev.com'),
// Update source. Defaults to the PUBLIC repo (safe to ship — it is public). install.sh overrides
// it via CLUSEV_REPOSITORY, derived from the clone origin: dev points at Gitea, staging at the
// GitHub-private mirror, public users at the public repo. Private (Gitea/GitHub-private) URLs live

View File

@ -525,7 +525,9 @@ document.addEventListener('alpine:init', () => {
// translated via __()), so the palette stays in sync with the active locale.
// CMDK_GO maps leader-key mnemonics to routes (i=dIenste, l=Log,
// e=Einstellungen, y=sYstem — d/s already taken) and stays in JS.
const CMDK_GO = { d: '/', s: '/servers', i: '/services', f: '/files', l: '/audit', e: '/settings', y: '/system', v: '/versions', h: '/help', t: '/terminal' };
// `h` (Help) is intentionally absent — it resolves via the config-driven nav list in go()
// so it can point at the external docs URL instead of an in-app route.
const CMDK_GO = { d: '/', s: '/servers', i: '/services', f: '/files', l: '/audit', e: '/settings', y: '/system', v: '/versions', t: '/terminal' };
window.Alpine.data('cmdk', (nav = [], actions = [], servers = [], failMsg = '') => ({
nav,
@ -613,6 +615,8 @@ document.addEventListener('alpine:init', () => {
navigate(href) {
this.close();
// Absolute URLs (e.g. the online docs) open in a new tab; in-app routes use SPA nav.
if (/^https?:\/\//i.test(href)) { window.open(href, '_blank', 'noopener'); return; }
if (window.Livewire?.navigate) window.Livewire.navigate(href);
else window.location.href = href;
},
@ -629,7 +633,11 @@ document.addEventListener('alpine:init', () => {
},
go(key) {
if (CMDK_GO[key]) this.navigate(CMDK_GO[key]);
if (CMDK_GO[key]) { this.navigate(CMDK_GO[key]); return; }
// Keys not in the static map resolve via the (translated, config-driven) nav list —
// e.g. "g h" → the Help entry, whose href points at the online docs.
const item = this.nav.find((n) => n.hint === `g ${key}`);
if (item?.href) this.navigate(item.href);
},
onKey(e) {

View File

@ -28,7 +28,7 @@
['label' => __('shell.nav_settings'), 'href' => '/settings', 'hint' => 'g e'],
['label' => __('shell.nav_system'), 'href' => '/system', 'hint' => 'g y'],
['label' => __('shell.nav_versions'), 'href' => '/versions', 'hint' => 'g v'],
['label' => __('shell.nav_help'), 'href' => '/help', 'hint' => 'g h'],
['label' => __('shell.nav_help'), 'href' => config('clusev.docs_url'), 'hint' => 'g h'],
];
$actions = [

View File

@ -45,7 +45,8 @@
{{ __('release.nav') }}
</x-nav-item>
@endif
<x-nav-item icon="help-circle" href="/help" :active="request()->is('help*')">{{ __('shell.nav_help') }}</x-nav-item>
{{-- Help opens the online docs (docs.clusev.com) in a new tab no in-panel duplication. --}}
<x-nav-item icon="help-circle" :href="config('clusev.docs_url')" target="_blank" rel="noopener">{{ __('shell.nav_help') }}</x-nav-item>
</nav>
{{-- User --}}