Remove system status section from settings
This commit is contained in:
@@ -110,7 +110,7 @@
|
|||||||
? [{ href: '/scripts', label: 'Scripts' }, { href: '/configs', label: 'Configs' }, { href: '/plugins', label: 'Plugins' }]
|
? [{ href: '/scripts', label: 'Scripts' }, { href: '/configs', label: 'Configs' }, { href: '/plugins', label: 'Plugins' }]
|
||||||
: tabs[2].match($page.url.pathname)
|
: tabs[2].match($page.url.pathname)
|
||||||
? [{ href: '/deployments', label: 'Server deployments' }, { href: '/campaigns', label: 'Campaigns' }]
|
? [{ href: '/deployments', label: 'Server deployments' }, { href: '/campaigns', label: 'Campaigns' }]
|
||||||
: tabs[4].match($page.url.pathname) ? [{ href: '/settings', label: 'Preferences & status' }, { href: '/server-keys', label: 'Server keys' }] : []);
|
: tabs[4].match($page.url.pathname) ? [{ href: '/settings', label: 'Preferences' }, { href: '/server-keys', label: 'Server keys' }] : []);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window onkeydown={closeMenu} />
|
<svelte:window onkeydown={closeMenu} />
|
||||||
@@ -149,7 +149,7 @@
|
|||||||
<Confirmation />
|
<Confirmation />
|
||||||
<NotificationHistory bind:open={notificationsOpen} />
|
<NotificationHistory bind:open={notificationsOpen} />
|
||||||
<Dialog bind:open={helpOpen} title="Keyboard shortcuts" description="Press g, then the destination key. Shortcuts are inactive while typing or using a dialog.">
|
<Dialog bind:open={helpOpen} title="Keyboard shortcuts" description="Press g, then the destination key. Shortcuts are inactive while typing or using a dialog.">
|
||||||
<dl class="shortcuts">{#each [['g f','Fleet'],['g s','Scripts'],['g c','Configs'],['g p','Plugins'],['g d','Server deployments'],['g a','Campaigns'],['g b','Betas'],['g h','System status'],['g k','Server keys'],['g l','Leaderboard'],['g m','Metrics'],['?','This help']] as [keys,label]}<div><dt><kbd>{keys}</kbd></dt><dd>{label}</dd></div>{/each}</dl>
|
<dl class="shortcuts">{#each [['g f','Fleet'],['g s','Scripts'],['g c','Configs'],['g p','Plugins'],['g d','Server deployments'],['g a','Campaigns'],['g b','Betas'],['g h','Settings'],['g k','Server keys'],['g l','Leaderboard'],['g m','Metrics'],['?','This help']] as [keys,label]}<div><dt><kbd>{keys}</kbd></dt><dd>{label}</dd></div>{/each}</dl>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,27 +2,11 @@
|
|||||||
import { timeFormat, timeZone, timeZonePersistenceError } from '$ui/stores/time-zone.js';
|
import { timeFormat, timeZone, timeZonePersistenceError } from '$ui/stores/time-zone.js';
|
||||||
import { availableTimeZones, DEFAULT_TIME_ZONE } from '$lib/time-zone.js';
|
import { availableTimeZones, DEFAULT_TIME_ZONE } from '$lib/time-zone.js';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import type { SystemStatus } from '$lib/system-status.js';
|
|
||||||
import SectionHeader from '$ui/components/primitives/SectionHeader.svelte';
|
import SectionHeader from '$ui/components/primitives/SectionHeader.svelte';
|
||||||
import Button from '$ui/components/primitives/Button.svelte';
|
|
||||||
import Badge from '$ui/components/primitives/Badge.svelte';
|
|
||||||
import PlutoniumMaintenance from '$ui/components/PlutoniumMaintenance.svelte';
|
import PlutoniumMaintenance from '$ui/components/PlutoniumMaintenance.svelte';
|
||||||
let data = $state<SystemStatus | null>(null);
|
let exampleDate = $state<Date | null>(null);
|
||||||
let loading = $state(false);
|
|
||||||
let error = $state('');
|
|
||||||
const zones = $derived([...new Set([...availableTimeZones(), $timeZone])].sort());
|
const zones = $derived([...new Set([...availableTimeZones(), $timeZone])].sort());
|
||||||
async function refresh(probe = false) {
|
onMount(() => { exampleDate = new Date(); });
|
||||||
if (loading) return;
|
|
||||||
loading = true; error = '';
|
|
||||||
try {
|
|
||||||
const response = await fetch('/api/system-status' + (probe ? '?probe=1' : ''));
|
|
||||||
if (!response.ok) throw new Error('Could not load system status. Try again.');
|
|
||||||
data = await response.json();
|
|
||||||
} catch (cause) { error = (cause as Error).message; }
|
|
||||||
finally { loading = false; }
|
|
||||||
}
|
|
||||||
onMount(() => { void refresh(); });
|
|
||||||
const labels = { ready: 'Ready', attention: 'Needs attention', unconfigured: 'Not configured', unverified: 'Not verified' };
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head><title>Settings · Electric Cherry</title></svelte:head>
|
<svelte:head><title>Settings · Electric Cherry</title></svelte:head>
|
||||||
@@ -36,37 +20,17 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<p id="timezone-help">Dates and times throughout the app use this timezone, including daylight saving changes. Saved automatically in this browser.</p>
|
<p id="timezone-help">Dates and times throughout the app use this timezone, including daylight saving changes. Saved automatically in this browser.</p>
|
||||||
{#if data}<p>Example: {$timeFormat.dateTime(data.checkedAt)}</p>{/if}
|
{#if exampleDate}<p>Example: {$timeFormat.dateTime(exampleDate)}</p>{/if}
|
||||||
{#if $timeZonePersistenceError}<p role="status">Browser storage is unavailable. Your timezone applies for this visit but cannot be saved.</p>{/if}
|
{#if $timeZonePersistenceError}<p role="status">Browser storage is unavailable. Your timezone applies for this visit but cannot be saved.</p>{/if}
|
||||||
</section>
|
</section>
|
||||||
<PlutoniumMaintenance />
|
<PlutoniumMaintenance />
|
||||||
<div class="heading">
|
|
||||||
<div><h2>System status</h2><p>Check your connections and the prerequisites for a playable server.</p></div>
|
|
||||||
<Button loading={loading} onclick={() => refresh(true)}>Check connections</Button>
|
|
||||||
</div>
|
|
||||||
{#if error}<p class="ui-error" role="alert">{error}<Button size="sm" onclick={() => refresh()}>Retry</Button></p>{/if}
|
|
||||||
{#if data}
|
|
||||||
<p class="checked">Checked {$timeFormat.dateTime(data.checkedAt)} · {data.readyServers} / {data.totalServers} servers ready</p>
|
|
||||||
<ol class="checks">{#each data.checks as check}<li><div class="heading"><h2>{check.title}</h2><Badge variant={check.state === 'ready' ? 'online' : check.state === 'unverified' ? 'neutral' : 'warning'}>{labels[check.state]}</Badge></div><p>{check.detail}</p>{#if check.href}<a href={check.href}>{check.action} →</a>{/if}</li>{/each}</ol>
|
|
||||||
{:else if loading}<p role="status">Checking system setup…</p>{/if}
|
|
||||||
<section id="setup-guide" class="guide"><h2>Connection setup</h2><p>Set these variables on the Electric Cherry container in Komodo, then restart the app to load the changes. Credentials are kept on the server and are never returned by this page.</p><dl><dt>Komodo</dt><dd><code>KOMODO_ADDRESS</code>, <code>KOMODO_API_KEY</code>, <code>KOMODO_API_SECRET</code>, and <code>KOMODO_TARGET_SERVER</code>. The target must match the host name in Komodo.</dd><dt>Game servers</dt><dd><code>RCON_PASSWORD</code> must match the game-server password. Set <code>RCON_HOST</code> if the default <code>host.docker.internal</code> does not reach the game host. Forward the allocated UDP game ports.</dd></dl></section>
|
|
||||||
<section id="game-files" class="guide"><h2>Game files and keys</h2><p>Populate the Komodo host's <code>t5_game_files</code> or <code>t6_game_files</code> Docker volume with the corresponding game files and required DLC. Override those names using <code>PLUTAINER_GAMEFILES_VOLUME</code> or <code>PLUTAINER_T6_GAMEFILES_VOLUME</code>. Electric Cherry and the host must see each server directory at the same absolute path.</p><p>Create a Plutonium server key for the correct game and save it for the exact game, map, and lobby in <a href="/server-keys">Server keys</a>. Use a launch preview to review the assigned ID and port before creating a server.</p></section>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.page { display: grid; gap: 20px; }
|
.page { display: grid; gap: 20px; }
|
||||||
.checked { color: var(--text-secondary); font-size: var(--text-xs); margin: 0; }
|
.guide { padding: 20px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); }
|
||||||
.checks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; list-style: none; margin: 0; padding: 0; }
|
|
||||||
.checks li, .guide { padding: 20px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); }
|
|
||||||
.heading { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; }
|
|
||||||
h2 { font-size: var(--text-md); margin: 0; }
|
h2 { font-size: var(--text-md); margin: 0; }
|
||||||
p, dd { font-size: var(--text-sm); color: var(--text-secondary); line-height: 1.65; }
|
p { font-size: var(--text-sm); color: var(--text-secondary); line-height: 1.65; }
|
||||||
a { font-size: var(--text-sm); }
|
|
||||||
dt { font-weight: var(--weight-semibold); margin-top: 12px; }
|
|
||||||
dd { margin: 5px 0 0; }
|
|
||||||
code { font-size: var(--text-xs); }
|
|
||||||
.guide { scroll-margin-top: 90px; }
|
|
||||||
.timezone { display: grid; gap: 8px; margin-top: 16px; font-size: var(--text-sm); max-width: 420px; }
|
.timezone { display: grid; gap: 8px; margin-top: 16px; font-size: var(--text-sm); max-width: 420px; }
|
||||||
.timezone select { width: 100%; padding: 10px 12px; font: inherit; color: var(--text-primary); background: var(--surface-sunken); border: 1px solid var(--border-control); border-radius: var(--radius-sm); }
|
.timezone select { width: 100%; padding: 10px 12px; font: inherit; color: var(--text-primary); background: var(--surface-sunken); border: 1px solid var(--border-control); border-radius: var(--radius-sm); }
|
||||||
@media (max-width: 700px) { .checks { grid-template-columns: 1fr; } }
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user