packages/web: add paste-from-clipboard in compare mode; fix overlaps

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I7311a4592d148ebbe8ab72b5091b82a46a6a6964
This commit is contained in:
raf 2026-04-14 09:46:42 +03:00
commit 697f1f1c73
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
3 changed files with 216 additions and 10 deletions

View file

@ -32,6 +32,7 @@ function App() {
const [showHelp, setShowHelp] = createSignal(false);
const [showManageSnapshots, setShowManageSnapshots] = createSignal(false);
const [precision, setPrecision] = createSignal(2);
const [pasteMode, setPasteMode] = createSignal<'advance' | 'replace'>('advance');
const [isLoading, setIsLoading] = createSignal(true);
const STORAGE_KEY = 'ns-data';
@ -62,6 +63,9 @@ function App() {
if (typeof parsed.precision === 'number' && parsed.precision >= 0) {
setPrecision(parsed.precision);
}
if (parsed.pasteMode === 'advance' || parsed.pasteMode === 'replace') {
setPasteMode(parsed.pasteMode);
}
}
} catch (e) {
console.warn('Failed to load saved data:', e);
@ -89,6 +93,7 @@ function App() {
snaps: ComparisonEntry[],
v: 'analysis' | 'compare',
prec: number,
pm: 'advance' | 'replace',
) => {
try {
localStorage.setItem(
@ -99,6 +104,7 @@ function App() {
currentRaw: raw,
view: v,
precision: prec,
pasteMode: pm,
}),
);
} catch (e) {
@ -115,10 +121,11 @@ function App() {
const snaps = snapshots();
const v = view();
const prec = precision();
const pm = pasteMode();
if (isLoading()) return;
saveToStorage(stats, raw, snaps, v, prec);
saveToStorage(stats, raw, snaps, v, prec, pm);
});
const saveSnapshot = () => {
@ -171,6 +178,27 @@ function App() {
}
};
const handlePasteStats = (text: string, name: string): ComparisonEntry | null => {
let raw: Record<string, unknown>;
let data: StatsData;
try {
raw = JSON.parse(text);
data = parseStats(raw);
} catch (e) {
console.error('Failed to parse pasted stats:', e);
return null;
}
const entry: ComparisonEntry = {
id: Date.now(),
name: name.trim() || `Snapshot ${snapshots().length + 1}`,
data,
raw,
timestamp: new Date(),
};
setSnapshots(prev => [...prev, entry]);
return entry;
};
return (
<div class="app">
<header class="header">
@ -264,6 +292,9 @@ function App() {
onSelect={entry => setCurrentStats(entry.data)}
onDelete={deleteSnapshot}
precision={precision()}
pasteMode={pasteMode()}
onPasteModeChange={setPasteMode}
onPasteStats={handlePasteStats}
/>
</Show>
</Show>