diff --git a/packages/web/src/components/ComparisonView.tsx b/packages/web/src/components/ComparisonView.tsx index 02e8fbc..8b58ad4 100644 --- a/packages/web/src/components/ComparisonView.tsx +++ b/packages/web/src/components/ComparisonView.tsx @@ -1,10 +1,11 @@ import { Component, For, createSignal, createMemo, Show, onMount, onCleanup } from 'solid-js'; -import { ComparisonEntry, calculateChange } from '@ns/core'; +import { ComparisonEntry, calculateChange, StatsData } from '@ns/core'; import { formatBytes, formatNumber, formatTime, formatPercent } from '@ns/ui-utils'; import ArrowRightIcon from 'lucide-solid/icons/arrow-right'; import ArrowDownIcon from 'lucide-solid/icons/arrow-down'; import ArrowUpIcon from 'lucide-solid/icons/arrow-up'; import XIcon from 'lucide-solid/icons/x'; +import FileUpload from './FileUpload'; interface ComparisonViewProps { entries: ComparisonEntry[]; @@ -14,6 +15,8 @@ interface ComparisonViewProps { pasteMode: 'advance' | 'replace'; onPasteModeChange: (mode: 'advance' | 'replace') => void; onPasteStats: (text: string, name: string) => ComparisonEntry | null; + onFileLoad: (data: StatsData, raw: Record) => void; + onTextLoad: (text: string) => void; } const ComparisonView: Component = props => { @@ -150,159 +153,189 @@ const ComparisonView: Component = props => { return (
-
-
- - -
-
- -
-
- - -
-
- - -
-
- - 0}> -
-

Saved Snapshots

- - {entry => ( -
- {entry.name} - -
- )} -
+ = 2}> +
+
+ + +
+
+ +
+
+ + +
+
+ + +
Select two snapshots to compare metrics
} - > -
-
-
Metric
-
{leftEntry()?.name}
-
{rightEntry()?.name}
-
Change
-
- - {row => ( -
-
- {row.label} -
-
- - N/A - -
-
- - N/A - -
-
- —}> - - - - - - - - {Math.abs(row.change).toFixed(prec())}% - - - } - > - - N/A - - + when={props.entries.length >= 2} + fallback={ +
+ + +
+
+ Upload or paste one more snapshot to start comparing
- )} - -
+ +
+ } + > + 0}> +
+

Saved Snapshots

+ + {entry => ( +
+ {entry.name} + +
+ )} +
+
+
-
- r.isReduction)}> -
- {' '} - {comparison()?.filter(r => r.isReduction && r.isDifferent).length} improved + +
Select two snapshots to compare metrics
+
+ Paste JSON stats here (Ctrl+V) while in compare mode +
-
- !r.isReduction && r.isDifferent)}> -
- {' '} - {comparison()?.filter(r => !r.isReduction && r.isDifferent).length} regressed + } + > +
+
+
Metric
+
{leftEntry()?.name}
+
{rightEntry()?.name}
+
Change
- -
+ + {row => ( +
+
+ {row.label} +
+
+ + N/A + +
+
+ + N/A + +
+
+ —}> + + + + + + + + {Math.abs(row.change).toFixed(prec())}% + + + } + > + + N/A + + +
+
+ )} +
+
+ +
+ r.isReduction)}> +
+ {' '} + {comparison()?.filter(r => r.isReduction && r.isDifferent).length} improved +
+
+ !r.isReduction && r.isDifferent)}> +
+ {' '} + {comparison()?.filter(r => !r.isReduction && r.isDifferent).length} regressed +
+
+
+
@@ -349,7 +382,7 @@ const ComparisonView: Component = props => { Cancel
diff --git a/packages/web/src/components/FileUpload.tsx b/packages/web/src/components/FileUpload.tsx index 95e5c20..1bb8c7f 100644 --- a/packages/web/src/components/FileUpload.tsx +++ b/packages/web/src/components/FileUpload.tsx @@ -6,16 +6,15 @@ import ClockIcon from 'lucide-solid/icons/clock'; interface FileUploadProps { onFileLoad: (data: StatsData, raw: Record) => void; onTextLoad: (text: string) => void; - showHelp: boolean; - onToggleHelp: () => void; snapshots?: ComparisonEntry[]; onLoadSnapshot?: (entry: ComparisonEntry) => void; } export default function FileUpload(props: FileUploadProps) { const [textInput, setTextInput] = createSignal(''); - const [isTextMode, setIsTextMode] = createSignal(false); + const [isTextMode, setIsTextMode] = createSignal(true); const [error, setError] = createSignal(''); + const [showHelp, setShowHelp] = createSignal(false); const handleFile = async (e: Event) => { const target = e.target as HTMLInputElement; @@ -49,11 +48,11 @@ export default function FileUpload(props: FileUploadProps) {

Load Statistics

-
+ + + @@ -295,6 +362,8 @@ function App() { pasteMode={pasteMode()} onPasteModeChange={setPasteMode} onPasteStats={handlePasteStats} + onFileLoad={handleCompareFileLoad} + onTextLoad={handleCompareTextLoad} /> diff --git a/packages/web/src/styles.css b/packages/web/src/styles.css index 17b5920..86e387d 100644 --- a/packages/web/src/styles.css +++ b/packages/web/src/styles.css @@ -183,6 +183,7 @@ body { align-items: center; gap: 2rem; padding-top: 4rem; + width: 100%; } .upload-card { @@ -1504,6 +1505,25 @@ body { border-radius: 0.75rem; } +.compare-placeholder-hint { + margin-top: 0.75rem; + font-size: 0.75rem; + color: var(--text-secondary); +} + +.compare-upload-section { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + width: 100%; +} + +.compare-more-needed { + text-align: center; + padding: 1rem; +} + .comparison-table { background: var(--card-bg); border: 1px solid var(--border-color);