fixed Dev mode

This commit is contained in:
Kelorastus
2026-09-29 15:54:26 +02:00
parent afbb597044
commit 0252f95e35
9 changed files with 266 additions and 141 deletions
-127
View File
@@ -62,7 +62,6 @@
trimmed.dev_target !== current.dev_target),
);
/** A drive's launcher needs a folder on a disk: a root or a share holds no install. */
const dev = $derived(launcher.status?.dev ?? null);
const offDrive = $derived(portable && trimmed.install_dir !== "" && !/^[A-Za-z]:\\.+/.test(trimmed.install_dir));
// Blank is a deliberate answer for all three: no DHP, no sign-in service, no AI. It is
// how a PC is put fully offline on purpose - and how an offline site is rehearsed on a
@@ -294,82 +293,6 @@
</div>
</fieldset>
{#if dev}
<!-- Only ever rendered on a PC holding a valid signed licence. An operator's
launcher has no dev section at all, which is the point of the signature. -->
<section class="group" aria-labelledby="set-dev-title">
<h3 id="set-dev-title" class="eyebrow">Dev</h3>
<p class="text">
{#if dev.machine}This PC{:else}This install{/if} carries a dev licence, valid until
<strong>{dev.expires_at}</strong>{#if dev.note} — {dev.note}{/if}. Dev mode runs the
client from your checkout, in a console, over this install's database and tiles.
</p>
<div class="field">
<label class="field-label" for="set-dev-root">Checkout folder</label>
<div class="row">
<input
id="set-dev-root"
class="input"
type="text"
spellcheck="false"
placeholder="E:\ODIAN_Dev"
bind:value={draft.dev_root}
disabled={locked || busy}
/>
<button type="button" class="btn" disabled={locked || busy} onclick={browseDev}>Browse…</button>
</div>
<p class="hint">The folder that holds <code>ODIAN_Engine</code>.</p>
</div>
<label class="check-row">
<input type="checkbox" bind:checked={draft.dev_mode} disabled={locked || busy || !draft.dev_root.trim()} />
<span>Launch the whole stack from the checkout instead of the installed version</span>
</label>
<label class="check-row">
<input type="checkbox" bind:checked={draft.dev_build} disabled={locked || busy || !draft.dev_mode} />
<span>Build it first, every launch</span>
</label>
<div class="field">
<span class="field-label" id="set-dev-target-label">Launch starts</span>
<div class="choices" role="radiogroup" aria-labelledby="set-dev-target-label">
{#each TARGETS as option (option.key)}
<label class="choice" class:on={draft.dev_target === option.key}>
<input
type="radio"
name="dev-target"
value={option.key}
bind:group={draft.dev_target}
disabled={locked || busy || !draft.dev_mode}
/>
<span class="choice-name">{option.name}</span>
<span class="choice-note">{option.note}</span>
</label>
{/each}
</div>
</div>
<div class="field">
<label class="field-label" for="set-dev-user">Run as</label>
<input
id="set-dev-user"
class="input"
type="text"
spellcheck="false"
placeholder={launcher.status?.operator ?? "the operator who signed in"}
bind:value={draft.dev_user}
disabled={locked || busy || !draft.dev_mode}
/>
<p class="hint">
{#if draft.dev_user.trim() && draft.dev_user.trim() !== launcher.status?.operator}
This PC will <strong>not sync with the DHP</strong> while it runs as someone else: work
authored as them would arrive there under your account.
{:else}
Another operator's name, to test what they see. Sync is switched off while it differs
from yours.
{/if}
</p>
</div>
</section>
{/if}
<section class="group" aria-labelledby="set-drive-title">
<h3 id="set-drive-title" class="eyebrow">Install from drive</h3>
<p class="text">
@@ -447,56 +370,6 @@
</dialog>
<style>
/* The Dev section's own rows. Only ever drawn on a licensed PC. */
.check-row {
display: flex;
align-items: flex-start;
gap: 0.5rem;
margin-top: 0.6rem;
line-height: 1.35;
}
.check-row input {
margin-top: 0.15rem;
flex: none;
}
.hint {
margin: 0.35rem 0 0;
font-size: 0.82rem;
line-height: 1.45;
color: var(--text-dim, #9aa3ad);
}
.choices {
display: flex;
flex-direction: column;
gap: 0.35rem;
margin-top: 0.4rem;
}
.choice {
display: grid;
grid-template-columns: auto auto 1fr;
align-items: baseline;
gap: 0.5rem;
padding: 0.4rem 0.55rem;
border: 1px solid var(--border, #2a3139);
border-radius: 6px;
cursor: pointer;
}
.choice.on {
border-color: var(--accent, #5b8cff);
background: color-mix(in srgb, var(--accent, #5b8cff) 12%, transparent);
}
.choice:has(input:disabled) {
opacity: 0.5;
cursor: default;
}
.choice-name {
font-weight: 600;
}
.choice-note {
font-size: 0.8rem;
color: var(--text-dim, #9aa3ad);
}
.drawer {
position: fixed;
inset: 0 0 0 auto;