diff --git a/src/lib/components/SchemaForm.svelte b/src/lib/components/SchemaForm.svelte
index 5e959c9..a976b3b 100644
--- a/src/lib/components/SchemaForm.svelte
+++ b/src/lib/components/SchemaForm.svelte
@@ -1,25 +1,35 @@
+
+
+
+
+ {#if showTemplateSwitcher}
+
+ {/if}
+
+ {#if pendingMigration}
+
+ {/if}
+
+
+
{#if suggestion}
@@ -94,3 +148,50 @@
/>
{/each}
+
+{#if showMigrationModal && pendingMigration}
+
{ showMigrationModal = false; }}>
+ Template Update
+ The {pendingMigration.preset.name} template has been updated:
+
+ {#each pendingMigration.diff.renamedFields as r}
+ - {r.from} → {r.to}
+ {/each}
+ {#each pendingMigration.diff.addedRecords as r}
+ - + New record: {r}
+ {/each}
+ {#each pendingMigration.diff.removedRecords as r}
+ - - Removed record: {r}
+ {/each}
+ {#each pendingMigration.diff.addedFields as f}
+ - + New field: {f}
+ {/each}
+ {#each pendingMigration.diff.removedFields as f}
+ - - Removed field: {f}
+ {/each}
+
+ Your existing data will be preserved.
+
+
+
+
+
+{/if}
+
+
{
+ if (showTemplateSwitcher) {
+ showTemplateSwitcher = false;
+ }
+}} />
diff --git a/src/lib/components/UpgradeModal.svelte b/src/lib/components/UpgradeModal.svelte
deleted file mode 100644
index 8a9fdc7..0000000
--- a/src/lib/components/UpgradeModal.svelte
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-{#if upgrades.length > 0}
-
- Templates Updated
-
- {#each upgrades as upgrade}
-
-
{upgrade.characterName}
-
{upgrade.templateName} template
-
- {#each upgrade.diff.renamedFields as r}
- - {r.from} → {r.to}
- {/each}
- {#each upgrade.diff.addedRecords as r}
- - + New record: {r}
- {/each}
- {#each upgrade.diff.removedRecords as r}
- - - Removed record: {r}
- {/each}
- {#each upgrade.diff.addedFields as f}
- - + New field: {f}
- {/each}
- {#each upgrade.diff.removedFields as f}
- - - Removed field: {f}
- {/each}
-
-
-
-
-
-
- {/each}
-
- Your existing data will be preserved. Skipped updates will be offered again next time.
-
-{/if}
diff --git a/src/lib/state.svelte.ts b/src/lib/state.svelte.ts
index 5cd6485..2c8c4d5 100644
--- a/src/lib/state.svelte.ts
+++ b/src/lib/state.svelte.ts
@@ -1,38 +1,14 @@
import { getAllCharacters, saveCharacter, deleteCharacter } from './storage';
import { isBlankCharacter } from './utils/blank';
-import { presets } from './presets';
-import { diffTemplates, hasChanges, type TemplateDiff } from './utils/template-diff';
import { slugify } from './utils/slugify';
import type { Character, Template } from './types';
-export interface PendingUpgrade {
- characterId: string;
- characterName: string;
- templateName: string;
- preset: Template;
- diff: TemplateDiff;
-}
-
let characters = $state([]);
let activeId = $state(null);
let saveStatus = $state<'idle' | 'saving' | 'saved'>('idle');
-let pendingUpgrades = $state([]);
let saveTimer: ReturnType | null = null;
let statusTimer: ReturnType | null = null;
-function getSkippedUpgrades(): Record {
- try {
- return JSON.parse(localStorage.getItem('skippedUpgrades') || '{}');
- } catch {
- return {};
- }
-}
-
-function upgradeFingerprint(preset: Template): string {
- const fields = preset.records.flatMap((r) => r.fields.map((f) => f.label)).sort();
- return `${preset.id}:${fields.join(',')}`;
-}
-
function migrateData(char: Character, preset: Template) {
for (const record of preset.records) {
for (const field of record.fields) {
@@ -52,84 +28,30 @@ function migrateData(char: Character, preset: Template) {
}
}
-function charDisplayName(char: Character): string {
- return (char.data['name'] as string)
- || (char.data['designation'] as string)
- || 'Unnamed Character';
-}
-
export const roster = {
get characters() { return characters; },
get active() { return characters.find((c) => c.id === activeId) ?? null; },
get saveStatus() { return saveStatus; },
- get pendingUpgrades() { return pendingUpgrades; },
- clearUpgrades() {
- pendingUpgrades = [];
- },
-
- async applyUpgrade(characterId: string) {
- const upgrade = pendingUpgrades.find((u) => u.characterId === characterId);
- const char = characters.find((c) => c.id === characterId);
- if (!upgrade || !char) return;
-
- migrateData(char, upgrade.preset);
- char.template = upgrade.preset;
+ async migrateToPreset(char: Character, preset: Template) {
+ migrateData(char, preset);
+ char.template = $state.snapshot(preset);
await saveCharacter($state.snapshot(char));
- const skipped = getSkippedUpgrades();
- delete skipped[characterId];
- localStorage.setItem('skippedUpgrades', JSON.stringify(skipped));
- pendingUpgrades = pendingUpgrades.filter((u) => u.characterId !== characterId);
- },
-
- skipUpgrade(characterId: string) {
- const upgrade = pendingUpgrades.find((u) => u.characterId === characterId);
- if (upgrade) {
- const skipped = getSkippedUpgrades();
- skipped[characterId] = upgradeFingerprint(upgrade.preset);
- localStorage.setItem('skippedUpgrades', JSON.stringify(skipped));
- }
- pendingUpgrades = pendingUpgrades.filter((u) => u.characterId !== characterId);
},
async load() {
const all = await getAllCharacters();
const kept: Character[] = [];
- const upgrades: PendingUpgrade[] = [];
- const skipped = getSkippedUpgrades();
for (const char of all) {
if (isBlankCharacter(char)) {
await deleteCharacter(char.id);
- continue;
+ } else {
+ kept.push(char);
}
-
- if (char.template.id.startsWith('preset:')) {
- const preset = presets.find((p) => p.id === char.template.id);
- if (preset) {
- const diff = diffTemplates(char.template, preset);
- if (hasChanges(diff)) {
- const fp = upgradeFingerprint(preset);
- if (skipped[char.id] === fp) {
- kept.push(char);
- continue;
- }
- upgrades.push({
- characterId: char.id,
- characterName: charDisplayName(char),
- templateName: preset.name,
- preset,
- diff
- });
- }
- }
- }
-
- kept.push(char);
}
characters = kept;
- pendingUpgrades = upgrades;
const stored = localStorage.getItem('activeCharacterId');
if (stored && characters.some((c) => c.id === stored)) {
@@ -155,7 +77,6 @@ export const roster = {
async remove(id: string) {
characters = characters.filter((c) => c.id !== id);
await deleteCharacter(id);
- pendingUpgrades = pendingUpgrades.filter((u) => u.characterId !== id);
if (activeId === id) {
activeId = characters[0]?.id ?? null;
if (activeId) localStorage.setItem('activeCharacterId', activeId);
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 2388afe..8ae07f9 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -7,7 +7,6 @@
import { roster } from '$lib/state.svelte';
import { presets } from '$lib/presets';
import TemplatePicker from '$lib/components/TemplatePicker.svelte';
- import UpgradeModal from '$lib/components/UpgradeModal.svelte';
let importData = $state(null);
let mobileView = $state<'edit' | 'preview' | 'split'>('split');
@@ -104,5 +103,3 @@
{/if}
{/if}
-
-