mirror of
https://github.com/NotAShelf/nix-evaluator-stats.git
synced 2026-05-08 16:35:13 +00:00
jj commit -m "packages/web: add paste/upload snapshot flows; unify inputs"
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I7cb4e2ee6962e5d343cd52da6524b3596a6a6964
This commit is contained in:
parent
697f1f1c73
commit
1541046669
4 changed files with 288 additions and 156 deletions
|
|
@ -29,11 +29,12 @@ function App() {
|
|||
const [view, setView] = createSignal<'analysis' | 'compare'>('analysis');
|
||||
const [snapshotName, setSnapshotName] = createSignal('');
|
||||
const [showSaveDialog, setShowSaveDialog] = createSignal(false);
|
||||
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 [showOverrideModal, setShowOverrideModal] = createSignal(false);
|
||||
const [pendingOverrideText, setPendingOverrideText] = createSignal('');
|
||||
|
||||
const STORAGE_KEY = 'ns-data';
|
||||
|
||||
|
|
@ -80,8 +81,28 @@ function App() {
|
|||
};
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
|
||||
const handleAnalysisPaste = (e: ClipboardEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
|
||||
return;
|
||||
}
|
||||
const text = e.clipboardData?.getData('text');
|
||||
if (!text) return;
|
||||
try {
|
||||
JSON.parse(text);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
if (view() === 'analysis' && currentStats()) {
|
||||
setPendingOverrideText(text);
|
||||
setShowOverrideModal(true);
|
||||
}
|
||||
};
|
||||
document.addEventListener('paste', handleAnalysisPaste);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
document.removeEventListener('paste', handleAnalysisPaste);
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -199,6 +220,34 @@ function App() {
|
|||
return entry;
|
||||
};
|
||||
|
||||
const handleCompareFileLoad = (data: StatsData, raw: Record<string, unknown>) => {
|
||||
const entry: ComparisonEntry = {
|
||||
id: Date.now(),
|
||||
name: `Snapshot ${snapshots().length + 1}`,
|
||||
data,
|
||||
raw,
|
||||
timestamp: new Date(),
|
||||
};
|
||||
setSnapshots(prev => [...prev, entry]);
|
||||
};
|
||||
|
||||
const handleCompareTextLoad = (text: string) => {
|
||||
try {
|
||||
const raw = JSON.parse(text);
|
||||
const data = parseStats(raw);
|
||||
const entry: ComparisonEntry = {
|
||||
id: Date.now(),
|
||||
name: `Snapshot ${snapshots().length + 1}`,
|
||||
data,
|
||||
raw,
|
||||
timestamp: new Date(),
|
||||
};
|
||||
setSnapshots(prev => [...prev, entry]);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse stats:', e);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="app">
|
||||
<header class="header">
|
||||
|
|
@ -209,11 +258,7 @@ function App() {
|
|||
<button class={view() === 'analysis' ? 'active' : ''} onClick={() => setView('analysis')}>
|
||||
Analysis
|
||||
</button>
|
||||
<button
|
||||
class={view() === 'compare' ? 'active' : ''}
|
||||
onClick={() => setView('compare')}
|
||||
disabled={snapshots().length < 2}
|
||||
>
|
||||
<button class={view() === 'compare' ? 'active' : ''} onClick={() => setView('compare')}>
|
||||
Compare ({snapshots().length})
|
||||
</button>
|
||||
<Show when={snapshots().length > 0}>
|
||||
|
|
@ -251,8 +296,6 @@ function App() {
|
|||
<FileUpload
|
||||
onFileLoad={handleFileLoad}
|
||||
onTextLoad={loadFromText}
|
||||
showHelp={showHelp()}
|
||||
onToggleHelp={() => setShowHelp(!showHelp())}
|
||||
snapshots={snapshots()}
|
||||
onLoadSnapshot={loadSnapshot}
|
||||
/>
|
||||
|
|
@ -283,6 +326,30 @@ function App() {
|
|||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={showOverrideModal()}>
|
||||
<div class="modal-overlay" onClick={() => setShowOverrideModal(false)}>
|
||||
<div class="modal" onClick={e => e.stopPropagation()}>
|
||||
<h3>Override Analysis?</h3>
|
||||
<p style={{ color: 'var(--text-secondary)', 'margin-bottom': '1rem' }}>
|
||||
This will replace the current analysis with pasted data.
|
||||
</p>
|
||||
<div class="modal-actions">
|
||||
<button class="cancel-btn" onClick={() => setShowOverrideModal(false)}>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="confirm-btn"
|
||||
onClick={() => {
|
||||
loadFromText(pendingOverrideText());
|
||||
setShowOverrideModal(false);
|
||||
}}
|
||||
>
|
||||
Override
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</Show>
|
||||
</Show>
|
||||
|
||||
|
|
@ -295,6 +362,8 @@ function App() {
|
|||
pasteMode={pasteMode()}
|
||||
onPasteModeChange={setPasteMode}
|
||||
onPasteStats={handlePasteStats}
|
||||
onFileLoad={handleCompareFileLoad}
|
||||
onTextLoad={handleCompareTextLoad}
|
||||
/>
|
||||
</Show>
|
||||
</Show>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue