fix(tui): render skill load errors inline (#33298)
This commit is contained in:
parent
06dae383f7
commit
9dadc2455f
@ -1,7 +1,10 @@
|
||||
import { TextAttributes } from "@opentui/core"
|
||||
import { DialogSelect, type DialogSelectOption } from "../ui/dialog-select"
|
||||
import { createResource, createMemo } from "solid-js"
|
||||
import { createResource, createMemo, createSignal } from "solid-js"
|
||||
import { useDialog } from "../ui/dialog"
|
||||
import { useSDK } from "../context/sdk"
|
||||
import { useTheme } from "../context/theme"
|
||||
import { errorMessage } from "../util/error"
|
||||
|
||||
export type DialogSkillProps = {
|
||||
onSelect: (skill: string) => void
|
||||
@ -10,14 +13,27 @@ export type DialogSkillProps = {
|
||||
export function DialogSkill(props: DialogSkillProps) {
|
||||
const dialog = useDialog()
|
||||
const sdk = useSDK()
|
||||
const { theme } = useTheme()
|
||||
dialog.setSize("large")
|
||||
|
||||
const [skills] = createResource(async () => {
|
||||
const result = await sdk.client.app.skills()
|
||||
return result.data ?? []
|
||||
})
|
||||
const [loadError, setLoadError] = createSignal<unknown>()
|
||||
|
||||
const [skills] = createResource(() =>
|
||||
sdk.client.app
|
||||
.skills({}, { throwOnError: true })
|
||||
.then((result) => result.data ?? [])
|
||||
// Catch so the rejected resource never reaches the memo below: reading
|
||||
// skills() in an errored state re-throws and tears down the dialog.
|
||||
.catch((error) => {
|
||||
setLoadError(error)
|
||||
return undefined
|
||||
}),
|
||||
)
|
||||
|
||||
const showError = createMemo(() => Boolean(loadError()))
|
||||
|
||||
const options = createMemo<DialogSelectOption<string>[]>(() => {
|
||||
if (showError()) return []
|
||||
const list = skills() ?? []
|
||||
const maxWidth = Math.max(0, ...list.map((s) => s.name.length))
|
||||
return list.map((skill) => ({
|
||||
@ -32,5 +48,23 @@ export function DialogSkill(props: DialogSkillProps) {
|
||||
}))
|
||||
})
|
||||
|
||||
return <DialogSelect title="Skills" placeholder="Search skills..." options={options()} />
|
||||
return (
|
||||
<DialogSelect
|
||||
title="Skills"
|
||||
placeholder="Search skills..."
|
||||
options={options()}
|
||||
renderFilter={!showError()}
|
||||
locked={showError()}
|
||||
emptyView={
|
||||
showError() ? (
|
||||
<box paddingLeft={4} paddingRight={4}>
|
||||
<text fg={theme.error} attributes={TextAttributes.BOLD}>
|
||||
Could not load skills
|
||||
</text>
|
||||
<text fg={theme.textMuted}>{errorMessage(loadError())}</text>
|
||||
</box>
|
||||
) : undefined
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user