Feature: Show runtime errors within files that are being imported (#5500)

* chore: dumping progress

* chore: saving progress

* fix: Got a working example of filenames piped from Rust to TS

* fix: cleaning up debugging code

* fix: TS type for filenames

* fix: rust linter errors

* fix: cargo fmt

* fix: testing code, updating KCLError class for filenames

* fix: auto fixes

* feat: display badge in project folder if there is an error in another file

* chore: skeleton ideas for badge notifications from errors in imported files

* fix: more skeleton code to test some potential implementations

* fix: addressing PR comments

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* fix: fixing the rust struct?

* fix: cargo fmt

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* feat: skeleton workflow for showing runtime errors

* chore: showBadge, adding more props

* fix: new application state to reset errors from previous execution if parse fails first

* fix: cleanup

* fix: better UI

* fix: adding comment for future

* fix: revert for production

* fix: removing unused comment

* chore: swapping JS object to typed Map

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Kevin Nadro
2025-02-25 13:18:59 -06:00
committed by GitHub
parent 9ab3325580
commit dcfcdc98ce
7 changed files with 113 additions and 14 deletions

View File

@ -18,6 +18,7 @@ import { editorManager } from 'lib/singletons'
import { ContextFrom } from 'xstate'
import { settingsMachine } from 'machines/settingsMachine'
import { FeatureTreePane } from './FeatureTreePane'
import { kclErrorsByFilename } from 'lang/errors'
export type SidebarType =
| 'code'
@ -30,8 +31,10 @@ export type SidebarType =
| 'variables'
export interface BadgeInfo {
value: (props: PaneCallbackProps) => boolean | number
value: (props: PaneCallbackProps) => boolean | number | string
onClick?: MouseEventHandler<any>
className?: string
title?: string
}
/**
@ -152,6 +155,25 @@ export const sidebarPanes: SidebarPane[] = [
},
keybinding: 'Shift + F',
hide: ({ platform }) => platform === 'web',
showBadge: {
value: (context) => {
// Only compute runtime errors! Compilation errors are not tracked here.
const errors = kclErrorsByFilename(context.kclContext.errors)
return errors.size > 0 ? 'x' : ''
},
onClick: (e) => {
e.preventDefault()
// TODO: When we have generic file open
// If badge is pressed
// Open the first error in the array of errors
// Then scroll to error
// Do you automatically open the project files
// editorManager.scrollToFirstErrorDiagnosticIfExists()
},
className:
'absolute m-0 p-0 bottom-4 left-4 w-3 h-3 flex items-center justify-center text-[9px] font-semibold text-white bg-red-600 rounded-full border border-red-300 dark:border-red-800 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200',
title: 'Project files have runtime errors',
},
},
{
id: 'variables',

View File

@ -27,8 +27,10 @@ interface ModelingSidebarProps {
}
interface BadgeInfoComputed {
value: number | boolean
value: number | boolean | string
onClick?: MouseEventHandler<any>
className?: string
title?: string
}
function getPlatformString(): 'web' | 'desktop' {
@ -116,6 +118,8 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
acc[pane.id] = {
value: pane.showBadge.value(paneCallbackProps),
onClick: pane.showBadge.onClick,
className: pane.showBadge.className,
title: pane.showBadge.title,
}
}
return acc
@ -125,6 +129,7 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
// Clear any hidden panes from the `openPanes` array
useEffect(() => {
const panesToReset: SidebarType[] = []
sidebarPanes.forEach((pane) => {
if (
pane.hide === true ||
@ -339,22 +344,31 @@ function ModelingPaneButton({
<p
id={`${paneConfig.id}-badge`}
className={
'absolute m-0 p-0 bottom-4 left-4 w-3 h-3 flex items-center justify-center text-[10px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200'
showBadge.className
? showBadge.className
: 'absolute m-0 p-0 bottom-4 left-4 w-3 h-3 flex items-center justify-center text-[10px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200'
}
onClick={showBadge.onClick}
title={`Click to view ${showBadge.value} notification${
Number(showBadge.value) > 1 ? 's' : ''
}`}
title={
showBadge.title
? showBadge.title
: `Click to view ${showBadge.value} notification${
Number(showBadge.value) > 1 ? 's' : ''
}`
}
>
<span className="sr-only">&nbsp;has&nbsp;</span>
{typeof showBadge.value === 'number' ? (
{typeof showBadge.value === 'number' ||
typeof showBadge.value === 'string' ? (
<span>{showBadge.value}</span>
) : (
<span className="sr-only">a</span>
)}
<span className="sr-only">
&nbsp;notification{Number(showBadge.value) > 1 ? 's' : ''}
</span>
{typeof showBadge.value === 'number' && (
<span className="sr-only">
&nbsp;notification{Number(showBadge.value) > 1 ? 's' : ''}
</span>
)}
</p>
)}
</div>