feat(frontend): Display error as an icon in order to avoid clutter wh… (#1143)

* feat(frontend): Display error as an icon in order to avoid clutter when an error occures

* feat(frontend): Fix build

* feat(frontend): Fix error icon position
This commit is contained in:
Faton Ramadani
2023-01-23 18:03:31 +01:00
committed by GitHub
parent 0172587b12
commit 22b8fed9d9
9 changed files with 74 additions and 32 deletions
@@ -54,7 +54,6 @@
<RunnableWrapper
defaultUserInput
noMinH
bind:runnableComponent
bind:componentInput
{id}
@@ -89,7 +89,6 @@
>
<RunnableWrapper
defaultUserInput
noMinH
bind:runnableComponent
bind:componentInput
{id}
@@ -21,13 +21,20 @@
export let autoRefresh: boolean = true
export let result: any = undefined
export let forceSchemaDisplay: boolean = false
export let noMinH = false
export let defaultUserInput = false
export let flexWrap = false
export let wrapperClass = ''
const { worldStore, runnableComponents, workspace, appPath, isEditor, jobs, noBackend } =
getContext<AppEditorContext>('AppEditorContext')
const {
worldStore,
runnableComponents,
workspace,
appPath,
isEditor,
jobs,
noBackend,
errorByComponent
} = getContext<AppEditorContext>('AppEditorContext')
onMount(() => {
if (autoRefresh) {
@@ -245,7 +252,14 @@
export async function runComponent() {
await executeComponent()
}
let lastStartedAt: number = Date.now()
function recordError(error: string) {
$errorByComponent[id] = error
}
$: result?.error && recordError(result.error)
</script>
{#each Object.entries(fields ?? {}) as [key, v]}
@@ -268,6 +282,11 @@
lastStartedAt = startedAt
outputs.result?.set(testJob?.result)
result = testJob.result
if ($errorByComponent[id] && !result?.error) {
delete $errorByComponent[id]
$errorByComponent = $errorByComponent
}
}
}
}}
@@ -299,17 +318,6 @@
<Alert type="warning" size="xs" class="mt-2 px-1" title="Missing runnable">
Please select a runnable
</Alert>
{:else if result?.error}
<div class="p-2">
<Alert type="error" title="Error during execution">
See "Debug Runs" on the top right for more details
<pre
title={JSON.stringify(result.error, null, 4)}
class=" mt-2 text-2xs whitespace-pre-wrap">{JSON.stringify(result.error, null, 4)}</pre
>
</Alert>
<slot />
</div>
{:else}
<div class="block w-full h-full">
<slot />
@@ -9,7 +9,6 @@
export let componentInput: AppInput | undefined
export let id: string
export let result: any = undefined
export let noMinH = false
export let extraQueryParams: Record<string, any> = {}
export let autoRefresh: boolean = true
@@ -47,7 +46,6 @@
{id}
{extraQueryParams}
{forceSchemaDisplay}
{noMinH}
wrapperClass={runnableClass}
>
<slot />
@@ -54,6 +54,7 @@
})
const runnableComponents = writable<Record<string, () => Promise<void>>>({})
const errorByComponent = writable<Record<string, string>>({})
setContext<AppEditorContext>('AppEditorContext', {
worldStore,
@@ -72,7 +73,8 @@
isEditor: true,
jobs: writable([]),
staticExporter: writable({}),
noBackend: false
noBackend: false,
errorByComponent
})
let timeout: NodeJS.Timeout | undefined = undefined
@@ -57,7 +57,7 @@
export let policy: Policy
const { app, summary, mode, breakpoint, appPath, jobs, staticExporter } =
const { app, summary, mode, breakpoint, appPath, jobs, staticExporter, errorByComponent } =
getContext<AppEditorContext>('AppEditorContext')
const loading = {
publish: false,
@@ -183,6 +183,7 @@
let testIsLoading = false
$: selectedJobId && testJobLoader?.watchJob(selectedJobId)
$: hasErrors = Object.keys($errorByComponent).length > 0
</script>
<TestJobLoader bind:this={testJobLoader} bind:isLoading={testIsLoading} bind:job />
@@ -243,12 +244,14 @@
{:else}
<div class="flex flex-col h-full w-full gap-4 mb-4">
{#if job?.['running']}
<div class="flex flex-row-reverse w-full"
><Button
<div class="flex flex-row-reverse w-full">
<Button
color="red"
variant="border"
on:click={() => testJobLoader?.cancelJob()}>Cancel</Button
on:click={() => testJobLoader?.cancelJob()}
>
Cancel
</Button>
</div>
{/if}
<div class="p-2">
@@ -436,7 +439,7 @@
<span class="hidden md:inline">
<Button
on:click={() => (jobsDrawerOpen = true)}
color="light"
color={hasErrors ? 'red' : 'light'}
size="xs"
variant="border"
startIcon={{ icon: faBug }}
@@ -59,7 +59,8 @@
isEditor,
jobs: writable([]),
staticExporter: writable({}),
noBackend
noBackend,
errorByComponent: writable({})
})
let mounted = false
@@ -74,8 +75,10 @@
</script>
<div class="relative">
<div class="{$$props.class} {lockedClasses} h-full max-h-[calc(100%-41px)] overflow-auto
w-full {app.fullscreen ? '' : 'max-w-6xl'} mx-auto">
<div
class="{$$props.class} {lockedClasses} h-full max-h-[calc(100%-41px)] overflow-auto
w-full {app.fullscreen ? '' : 'max-w-6xl'} mx-auto"
>
{#if $appStore.grid}
<div class={classNames('mx-auto pb-4', width)}>
<GridEditor {policy} />
@@ -86,10 +89,10 @@
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
transition:fade|local={{ duration: 200, easing: cubicOut }}
on:click={() => isLocked = false}
on:click={() => (isLocked = false)}
class="absolute inset-0 center-center bg-black/20 z-50 backdrop-blur-[1px] cursor-pointer"
>
<Button on:click={() => isLocked = false}>
<Button on:click={() => (isLocked = false)}>
Unlock preview
<Unlock size={18} class="ml-1" strokeWidth={2.5} />
</Button>
@@ -1,8 +1,10 @@
<script lang="ts">
import { classNames } from '$lib/utils'
import type { AppComponent } from '../types'
import { Anchor, Move } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
import type { AppComponent, AppEditorContext } from '../types'
import { Anchor, Bug, Move } from 'lucide-svelte'
import { createEventDispatcher, getContext } from 'svelte'
import Popover from '$lib/components/Popover.svelte'
import { Alert, Button } from '$lib/components/common'
export let component: AppComponent
export let selected: boolean
@@ -11,6 +13,10 @@
export let hover: boolean = false
const dispatch = createEventDispatcher()
const { errorByComponent } = getContext<AppEditorContext>('AppEditorContext')
$: error = $errorByComponent[component.id]
</script>
<span
@@ -56,3 +62,26 @@
<Move size={14} />
</span>
{/if}
{#if error}
<span
title="Error"
class={classNames(
'text-red-500 px-1 text-2xs py-0.5 font-bold w-fit absolute border border-red-500 -bottom-1 shadow left-1/2 transform -translate-x-1/2 z-50 cursor-pointer',
'bg-red-100/80'
)}
>
<Popover notClickable placement="bottom" popupClass="!bg-white border w-96">
<Bug size={14} />
<span slot="text">
<div class="bg-white">
<Alert type="error" title="Error during execution">
<div class="flex flex-col">
<span> See "Debug Runs" on the top right for more details </span>
</div>
</Alert>
</div>
</span>
</Popover>
</span>
{/if}
@@ -172,6 +172,7 @@ export type AppEditorContext = {
isEditor: boolean
jobs: Writable<{ job: string; component: string }[]>
noBackend: boolean
errorByComponent: Writable<Record<string, string>>
}
export type EditorMode = 'dnd' | 'preview'