Better restrict editing of the live configuration
This commit is contained in:
@@ -73,6 +73,10 @@
|
|||||||
return JSON.stringify(current) !== JSON.stringify(savedSnapshot);
|
return JSON.stringify(current) !== JSON.stringify(savedSnapshot);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isLive = $derived(
|
||||||
|
!!editor && editor.configId !== null && editor.configId === liveConfigId,
|
||||||
|
);
|
||||||
|
|
||||||
const selectedMetrics = $derived({
|
const selectedMetrics = $derived({
|
||||||
gender: metrics.gender,
|
gender: metrics.gender,
|
||||||
age: metrics.age ?? 0,
|
age: metrics.age ?? 0,
|
||||||
@@ -158,32 +162,39 @@
|
|||||||
editor.data = res.data.data;
|
editor.data = res.data.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function persist(mode: "update" | "create") {
|
async function persist(mode: "update" | "create", nameOverride?: string) {
|
||||||
if (!editor || !editor.name) return;
|
if (!editor) return;
|
||||||
|
const name = nameOverride ?? editor.name;
|
||||||
|
if (!name) return;
|
||||||
|
if (mode === "update" && editor.configId && editor.configId === liveConfigId)
|
||||||
|
return;
|
||||||
const target = editor;
|
const target = editor;
|
||||||
saveError = null;
|
saveError = null;
|
||||||
saving = true;
|
saving = true;
|
||||||
try {
|
try {
|
||||||
if (mode === "update" && target.configId) {
|
if (mode === "update" && target.configId) {
|
||||||
const res = await api.standards.configs({ id: target.configId }).put({
|
const res = await api.standards.configs({ id: target.configId }).put({
|
||||||
name: target.name,
|
name,
|
||||||
datasetId: target.datasetId,
|
datasetId: target.datasetId,
|
||||||
params: target.params,
|
params: target.params,
|
||||||
});
|
});
|
||||||
if (res.error) throw res.error;
|
if (res.error) throw res.error;
|
||||||
} else {
|
} else {
|
||||||
const res = await api.standards.configs.post({
|
const res = await api.standards.configs.post({
|
||||||
name: target.name,
|
name,
|
||||||
datasetId: target.datasetId,
|
datasetId: target.datasetId,
|
||||||
params: target.params,
|
params: target.params,
|
||||||
});
|
});
|
||||||
if (res.error) throw res.error;
|
if (res.error) throw res.error;
|
||||||
// only stamp the new id if the user hasn't switched away in the meantime
|
// only stamp the new id/name if the user hasn't switched away in the meantime
|
||||||
if (editor === target) editor.configId = res.data.id;
|
if (editor === target) {
|
||||||
|
editor.configId = res.data.id;
|
||||||
|
editor.name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (editor === target) {
|
if (editor === target) {
|
||||||
savedSnapshot = {
|
savedSnapshot = {
|
||||||
name: target.name,
|
name,
|
||||||
datasetId: target.datasetId,
|
datasetId: target.datasetId,
|
||||||
params: $state.snapshot(target.params),
|
params: $state.snapshot(target.params),
|
||||||
};
|
};
|
||||||
@@ -201,8 +212,16 @@
|
|||||||
return persist(editor?.configId ? "update" : "create");
|
return persist(editor?.configId ? "update" : "create");
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveAsNew() {
|
function promptSaveAsNew() {
|
||||||
return persist("create");
|
if (!editor) return;
|
||||||
|
const name = prompt(
|
||||||
|
"Name for the new configuration:",
|
||||||
|
editor.name ? `${editor.name} copy` : "",
|
||||||
|
);
|
||||||
|
if (name === null) return;
|
||||||
|
const trimmed = name.trim();
|
||||||
|
if (!trimmed) return;
|
||||||
|
return persist("create", trimmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function discard() {
|
async function discard() {
|
||||||
@@ -213,6 +232,12 @@
|
|||||||
async function setLive() {
|
async function setLive() {
|
||||||
if (!editor?.configId || isDirty) return;
|
if (!editor?.configId || isDirty) return;
|
||||||
const configId = editor.configId;
|
const configId = editor.configId;
|
||||||
|
if (
|
||||||
|
!confirm(
|
||||||
|
`Set "${editor.name || "(untitled)"}" as the live configuration? This will immediately affect live calculations.`,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return;
|
||||||
saveError = null;
|
saveError = null;
|
||||||
settingLive = true;
|
settingLive = true;
|
||||||
try {
|
try {
|
||||||
@@ -313,11 +338,27 @@
|
|||||||
</option>
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
|
<button
|
||||||
|
class="btn btn-ghost btn-sm btn-square"
|
||||||
|
title="Save as new configuration"
|
||||||
|
aria-label="Save as new configuration"
|
||||||
|
disabled={saving}
|
||||||
|
onclick={promptSaveAsNew}
|
||||||
|
>
|
||||||
|
<span class="text-lg leading-none">+</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
{#if isDirty}
|
{#if isDirty}
|
||||||
<span class="badge badge-warning badge-sm">Unsaved</span>
|
<span class="badge badge-warning badge-sm">Unsaved</span>
|
||||||
{:else if currentEditor.configId === liveConfigId}
|
{/if}
|
||||||
<span class="badge badge-success badge-sm">Live</span>
|
|
||||||
|
<div class="flex-1"></div>
|
||||||
|
|
||||||
|
{#if isLive}
|
||||||
|
<p class="text-sm text-info opacity-90">
|
||||||
|
This is the live configuration and is read-only — click "+"
|
||||||
|
to create an editable copy.
|
||||||
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
@@ -329,27 +370,21 @@
|
|||||||
>
|
>
|
||||||
Discard changes
|
Discard changes
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
class="btn btn-outline btn-sm"
|
|
||||||
hidden={currentEditor.configId === liveConfigId || isDirty}
|
|
||||||
disabled={settingLive || isDirty}
|
|
||||||
onclick={setLive}
|
|
||||||
>
|
|
||||||
{settingLive ? "Setting live..." : "Set as live"}
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary btn-sm"
|
class="btn btn-primary btn-sm"
|
||||||
disabled={saving || !isDirty}
|
hidden={isLive}
|
||||||
|
disabled={saving || !isDirty || isLive}
|
||||||
onclick={save}
|
onclick={save}
|
||||||
>
|
>
|
||||||
{saving ? "Saving..." : "Save"}
|
{saving ? "Saving..." : "Save"}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-outline btn-sm"
|
class="btn btn-outline btn-sm"
|
||||||
disabled={saving || !currentEditor.name}
|
hidden={currentEditor.configId === liveConfigId}
|
||||||
onclick={saveAsNew}
|
disabled={settingLive || isDirty}
|
||||||
|
onclick={setLive}
|
||||||
>
|
>
|
||||||
Save as new
|
{settingLive ? "Setting live..." : "Set as live"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -359,6 +394,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
<section class="w-full flex gap-4 flex-wrap mt-6">
|
<section class="w-full flex gap-4 flex-wrap mt-6">
|
||||||
<fieldset class="fieldset bg-base-200 p-4">
|
<fieldset class="fieldset bg-base-200 p-4">
|
||||||
<label class="flex flex-col gap-1">
|
<label class="flex flex-col gap-1">
|
||||||
@@ -374,6 +410,7 @@
|
|||||||
<select
|
<select
|
||||||
class="select select-sm w-36"
|
class="select select-sm w-36"
|
||||||
value={currentEditor.datasetId}
|
value={currentEditor.datasetId}
|
||||||
|
disabled={isLive}
|
||||||
onchange={(e) => onDatasetChange(e.currentTarget.value)}
|
onchange={(e) => onDatasetChange(e.currentTarget.value)}
|
||||||
>
|
>
|
||||||
{#each datasets as dataset}
|
{#each datasets as dataset}
|
||||||
@@ -385,6 +422,7 @@
|
|||||||
<span class="label text-xs">Max level</span>
|
<span class="label text-xs">Max level</span>
|
||||||
<input
|
<input
|
||||||
class="input input-sm w-36"
|
class="input input-sm w-36"
|
||||||
|
disabled={isLive}
|
||||||
type="number"
|
type="number"
|
||||||
min="1"
|
min="1"
|
||||||
max="100"
|
max="100"
|
||||||
@@ -414,7 +452,7 @@
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="flex gap-3 flex-wrap">
|
<div class="flex gap-3 flex-wrap">
|
||||||
<fieldset class="fieldset bg-base-300 p-2">
|
<fieldset class="fieldset bg-base-300 p-2" disabled={isLive}>
|
||||||
<legend class="fieldset-legend text-sm font-semibold"
|
<legend class="fieldset-legend text-sm font-semibold"
|
||||||
>Modifiers</legend
|
>Modifiers</legend
|
||||||
>
|
>
|
||||||
@@ -429,7 +467,7 @@
|
|||||||
/>
|
/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset class="fieldset bg-base-300 p-2">
|
<fieldset class="fieldset bg-base-300 p-2" disabled={isLive}>
|
||||||
<legend class="fieldset-legend text-sm font-semibold"
|
<legend class="fieldset-legend text-sm font-semibold"
|
||||||
>Generation</legend
|
>Generation</legend
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user