fix: show saved keys as ready in deployment previews
Replace saved-key inputs with a ready indicator and direct key updates to Keys. Clear hidden key overrides on preview refresh and update the blueprint documentation. Fixes #41
This commit is contained in:
@@ -26,8 +26,8 @@ destroy servers or change existing servers' files.
|
||||
1. Choose **Create blueprint** on Deployments and name the lineup.
|
||||
2. Add maps from Black Ops I or II and set the desired total lobbies for each.
|
||||
3. Choose **Save & preview** to review every new server ID and game port.
|
||||
4. Enter each lobby's Plutonium key, or leave its field blank to reuse the key
|
||||
saved for that exact server ID.
|
||||
4. Lobbies with a saved key show **Saved key ready** and reuse it automatically.
|
||||
Enter a Plutonium key only for lobbies missing one. Update saved keys in **Keys**.
|
||||
5. Choose **Queue N servers** and follow their collection progress page.
|
||||
If every target is already met, choose **Done**; no operation is created.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
if (current === session) {
|
||||
const next = body as CollectionPreview;
|
||||
const names = new Set(next.servers.map(server => server.name));
|
||||
keys = Object.fromEntries(next.servers.filter(server => server.name).map(server => [server.name!, keys[server.name!] ?? '']));
|
||||
keys = Object.fromEntries(next.servers.filter(server => server.name && !server.hasSavedKey).map(server => [server.name!, keys[server.name!] ?? '']));
|
||||
if (previous && (previous.servers.length !== next.servers.length || previous.servers.some(server => !names.has(server.name)))) keyNotice = 'Server assignments changed. Keys were retained only for the exact IDs still shown below. Review the new assignments.';
|
||||
else if (previous) keyNotice = 'Preview refreshed. Entered keys are retained for these same server IDs.';
|
||||
preview = next; now = Date.now();
|
||||
@@ -84,14 +84,17 @@
|
||||
<div class="section-title"><h3>{preview.servers.length ? 'Your launch order' : 'Nothing to create'}</h3><button class="text-button" disabled={busy} onclick={review}>Refresh preview</button></div>
|
||||
{#each preview.blockers as blocker}<p class="error" role="alert">{blocker}</p>{/each}
|
||||
{#if preview.servers.length}
|
||||
<p class="muted">Add a key for each new lobby below, or reuse its saved key. Fleet counts and available slots are checked again when you queue the launch.</p>
|
||||
<p class="muted">Saved keys are reused automatically. Add keys only where required below. Update saved keys in <a href="/server-keys" target="_blank" rel="noopener">Keys (opens in a new tab)</a>. Fleet counts and available slots are checked again when you queue the launch.</p>
|
||||
<form onsubmit={event => { event.preventDefault(); void launch(); }}>
|
||||
<ol class="servers" aria-label="Server launch order">
|
||||
{#each preview.servers as server, index (server.name ?? `unavailable-${index}`)}
|
||||
<li class="server-row">
|
||||
<span class="order" aria-hidden="true">{String(index + 1).padStart(2, '0')}</span>
|
||||
<div class="server-identity">{#if index === 0 || preview.servers[index - 1].entryIndex !== server.entryIndex}<span class="map-group">{preview.entries[server.entryIndex].recipe.game.toUpperCase()} · {preview.entries[server.entryIndex].recipe.mapName}</span>{/if}<strong>{#if server.name}<ServerIdentity name={server.name} />{:else}{preview.entries[server.entryIndex].recipe.mapName}{/if}</strong><span class="server-id">{server.name ?? 'No available lobby'} · {server.port === null ? 'No available port' : `Port ${server.port}`}</span></div>
|
||||
{#if server.name}<label><span>{server.hasSavedKey ? 'Saved key available' : 'Server key required'}</span><input aria-label={`Key for ${server.name}`} data-missing={!server.hasSavedKey && !keys[server.name]?.trim()} type="password" bind:value={keys[server.name]} disabled={busy} maxlength="512" autocomplete="off" placeholder={server.hasSavedKey ? 'Leave blank to reuse' : 'Paste this server’s key'} /></label>{/if}
|
||||
{#if server.name}
|
||||
{#if server.hasSavedKey}<p class="key-ready"><span aria-hidden="true">✓</span> Saved key ready</p>
|
||||
{:else}<label><span>Server key required</span><input aria-label={`Key for ${server.name}`} data-missing={!keys[server.name]?.trim()} type="password" bind:value={keys[server.name]} disabled={busy} maxlength="512" autocomplete="off" placeholder="Paste this server’s key" /></label>{/if}
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
</ol>
|
||||
@@ -104,6 +107,9 @@
|
||||
</dialog>
|
||||
|
||||
<style>
|
||||
.key-ready { color: var(--state-online); font-size: 13px; font-weight: 600; }
|
||||
a { color: var(--accent-primary-hover); }
|
||||
@media (max-width: 600px) { .server-row .key-ready { grid-column: 2; } }
|
||||
input { scroll-margin-block: 32px 190px; }
|
||||
.launch-footer { position: sticky; bottom: -28px; background: var(--surface); z-index: 2; padding: 16px 0 20px; border-top: 1px solid var(--border-strong); box-shadow: 0 -12px 16px var(--surface); }
|
||||
.map-group { font-size: 12px; color: var(--accent-primary-hover); }
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
if (!res.ok) throw new Error(body.error ?? 'Could not prepare launch preview.');
|
||||
if (current === session) {
|
||||
if (previousName && previousName !== body.name) { plutoKey = ''; keyNotice = 'The available server ID changed. Enter the key for the new ID below; the previous key was not transferred.'; }
|
||||
if (body.hasSavedKey) plutoKey = '';
|
||||
preview = body; now = Date.now();
|
||||
await tick(); heading?.focus();
|
||||
}
|
||||
@@ -133,8 +134,9 @@
|
||||
</section>
|
||||
<form onsubmit={event => { event.preventDefault(); void launch(); }}>
|
||||
<div class="identity"><span class="eyebrow">Your new server</span><strong>{preview.name ?? 'Waiting for an available lobby'}</strong><p>{preview.port ? `Port ${preview.port} · ` : ''}Fresh identity, with its own server key.</p></div>
|
||||
<label>Plutonium server key<input type="password" bind:value={plutoKey} disabled={busy || saving || !preview.name} maxlength="512" autocomplete="off" placeholder={preview.hasSavedKey ? 'Saved key available — leave blank to reuse' : 'Paste the key for this server ID'} /></label>
|
||||
<p class="muted">{preview.hasSavedKey ? 'A key is stored for this exact server ID; its validity is checked when the game starts. Enter a replacement here to update it at launch.' : 'Add the key here. It is saved for this exact server ID when you launch, including if provisioning fails.'} <a href={`/server-keys?server=${encodeURIComponent(preview.name ?? '')}`} target="_blank" rel="noopener">Manage saved keys in a new tab</a>; your launch stays open here.</p>
|
||||
{#if preview.hasSavedKey}<p class="key-ready"><span aria-hidden="true">✓</span> Saved key ready</p>
|
||||
{:else}<label>Plutonium server key<input type="password" bind:value={plutoKey} disabled={busy || saving || !preview.name} maxlength="512" autocomplete="off" placeholder="Paste the key for this server ID" /></label>{/if}
|
||||
<p class="muted">{preview.hasSavedKey ? 'The saved key for this server ID will be reused automatically. Its validity is checked when the game starts. Update it in Keys.' : 'Add the key here. It is saved for this exact server ID when you launch, including if provisioning fails.'} <a href={`/server-keys?server=${encodeURIComponent(preview.name ?? '')}`} target="_blank" rel="noopener">Manage saved keys in a new tab</a>; your launch stays open here.</p>
|
||||
<div class="launch-actions">{#if !sourceDeploymentId}<Button variant="ghost" disabled={busy || saving} onclick={() => { preview = null; plutoKey = ''; error = ''; }}>Back</Button>{/if}<Button type="submit" variant="primary" loading={busy} disabled={busy || saving || expired || !preview.ready || (!preview.hasSavedKey && !plutoKey.trim())}>Launch server</Button></div>
|
||||
{#if !preview.hasSavedKey && !plutoKey.trim()}<p class="muted">Enter this server’s key to enable launch.</p>{/if}
|
||||
<p class="caption">Preview valid until {$timeFormat.minuteTime(preview.expiresAt)}. Lobby and port availability are checked again at launch.</p>
|
||||
@@ -160,6 +162,7 @@
|
||||
<DeployCollectionDialog bind:open={collectionOpen} {blueprintId} />
|
||||
|
||||
<style>
|
||||
.key-ready { color: var(--state-online); font-weight: 600; }
|
||||
dialog { background: var(--surface); color: var(--text-primary); border: 1px solid var(--border-strong); border-radius: var(--radius-lg); padding: 0; width: min(700px, calc(100vw - 32px)); max-height: calc(100dvh - 40px); }
|
||||
dialog::backdrop { background: rgb(0 0 0 / .7); backdrop-filter: blur(5px); }
|
||||
.composer { display: grid; gap: 24px; padding: 30px; } header, .section-title { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
|
||||
|
||||
Reference in New Issue
Block a user