diff --git a/webview/src/components/MetaschemaStackTrace.tsx b/webview/src/components/MetaschemaStackTrace.tsx new file mode 100644 index 0000000..0973001 --- /dev/null +++ b/webview/src/components/MetaschemaStackTrace.tsx @@ -0,0 +1,122 @@ +import { useState } from "react"; +import type { MetaschemaError,Position } from "../../../protocol/cli"; +import { goToPosition } from "../message"; + +interface Props { + errors: MetaschemaError[]; +} + +function ErrorBox({ + error, + size, + indent +}: { + error: MetaschemaError; + size?: 'primary' | 'stack'; + indent: number; +}) { + const clickable = Boolean(error.instancePosition); + + return ( +
+ clickable && goToPosition(error.instancePosition as Position) + } + > +
+ {size === 'stack' && ( + + )} +
+
+ {error.error} +
+ {error.instanceLocation && ( +
+ {error.instanceLocation || "(root)"} +
+ )} +
+
+
+ ); +} + + +export function MetaschemaStackTrace({errors}:Props){ + const [expanded,setExpanded]= useState(false); + + if(errors.length===0) return null; + + const [primary, ...stack] = errors; + + if (!primary) return null; + + return ( +
+ {/* Top level error */} + + + {stack.length > 0 && ( + + )} + + {/* Stack trace */} +
+
+
+ { + stack.map((err,ind)=>{ + const STACK_INDENT = 16; + return ( +
+ + +
+ ) + }) + } +
+
+
+
+ ) +} + + diff --git a/webview/src/components/MetaschemaTab.tsx b/webview/src/components/MetaschemaTab.tsx index 224c075..c40e75a 100644 --- a/webview/src/components/MetaschemaTab.tsx +++ b/webview/src/components/MetaschemaTab.tsx @@ -2,6 +2,7 @@ import type { MetaschemaResult, MetaschemaError, Position } from '../../../proto import { goToPosition } from '../message'; import { RawOutput } from './RawOutput'; import { CheckCircle, AlertTriangle, FileQuestion } from 'lucide-react'; +import { MetaschemaStackTrace } from './MetaschemaStackTrace'; export interface MetaschemaTabProps { metaschemaResult: MetaschemaResult; @@ -55,55 +56,7 @@ export function MetaschemaTab({ metaschemaResult, noFileSelected }: MetaschemaTa return (
- {metaschemaErrors.map((error, index) => ( -
error.instancePosition && handleGoToPosition(error.instancePosition)} - > -
-
- {error.error} -
-
-
- {error.instancePosition && ( -
- - Location: - - - Line {error.instancePosition[0]}, Col {error.instancePosition[1]} - -
- )} - {error.instanceLocation && ( -
- - Path: - - - {error.instanceLocation || '(root)'} - -
- )} - {error.keywordLocation && ( -
- - Schema: - - - {error.keywordLocation} - -
- )} -
-
- ))} +
@@ -128,12 +81,12 @@ export function MetaschemaTab({ metaschemaResult, noFileSelected }: MetaschemaTa error && 'instancePosition' in error && error.instancePosition ? error.instancePosition : null; - + return ( <> -
( + items: T[], + containerWidth: number, + itemWidth: number, + gap: number +): T[][] { + const itemsPerRow = Math.max( + 1, + Math.floor((containerWidth + gap) / (itemWidth + gap)) + ); + + const rows: T[][] = []; + for (let i = 0; i < items.length; i += itemsPerRow) { + rows.push(items.slice(i, i + itemsPerRow)); + } + return rows; +} +