mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 08:02:26 +00:00
feat(frontend): App debug mode (#3252)
* feat(frontend): App debug mode * feat(frontend): App debug mode * feat(frontend): App debug mode * feat(frontend): App debug mode * feat(frontend): App debug mode done * feat(frontend): App debug mode done
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
import TabContent from '$lib/components/common/tabs/TabContent.svelte'
|
||||
import Tabs from '$lib/components/common/tabs/Tabs.svelte'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { classNames, encodeState } from '$lib/utils'
|
||||
import { classNames, encodeState, sendUserToast } from '$lib/utils'
|
||||
import AppPreview from './AppPreview.svelte'
|
||||
import ComponentList from './componentsPanel/ComponentList.svelte'
|
||||
import ContextPanel from './contextPanel/ContextPanel.svelte'
|
||||
@@ -119,6 +119,7 @@
|
||||
|
||||
const worldStore = buildWorld(context)
|
||||
const previewTheme: Writable<string | undefined> = writable(undefined)
|
||||
const initialized = writable({ initialized: false, initializedComponents: [] })
|
||||
|
||||
$secondaryMenuRightStore.isOpen = false
|
||||
$secondaryMenuLeftStore.isOpen = false
|
||||
@@ -127,7 +128,7 @@
|
||||
worldStore,
|
||||
app: appStore,
|
||||
summary: summaryStore,
|
||||
initialized: writable({ initialized: false, initializedComponents: [] }),
|
||||
initialized: initialized,
|
||||
selectedComponent,
|
||||
mode,
|
||||
connectingInput,
|
||||
@@ -470,6 +471,23 @@
|
||||
onMount(() => {
|
||||
mounted = true
|
||||
|
||||
setTimeout(() => {
|
||||
if ($initialized?.initialized === false) {
|
||||
sendUserToast(
|
||||
'App is not yet initialized, please check the Troubleshoot Panel for more information',
|
||||
true,
|
||||
[
|
||||
{
|
||||
label: 'Open Troubleshoot Panel',
|
||||
callback: () => {
|
||||
appEditorHeader?.openTroubleshootPanel()
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
}, 10000)
|
||||
|
||||
parseScroll()
|
||||
})
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
createUpdatePostgresInput,
|
||||
getPrimaryKeys
|
||||
} from '../components/display/dbtable/utils'
|
||||
import DebugPanel from './contextPanel/DebugPanel.svelte'
|
||||
|
||||
async function hash(message) {
|
||||
try {
|
||||
@@ -161,6 +162,7 @@
|
||||
let saveDrawerOpen = false
|
||||
let inputsDrawerOpen = fromHub
|
||||
let historyBrowserDrawerOpen = false
|
||||
let debugAppDrawerOpen = false
|
||||
let deploymentMsg: string | undefined = undefined
|
||||
|
||||
function closeSaveDrawer() {
|
||||
@@ -208,7 +210,6 @@
|
||||
const whereClause = (c.configuration.whereClause as any).value as unknown as
|
||||
| string
|
||||
| undefined
|
||||
console.log(columnDefs)
|
||||
if (tableValue && resourceValue && columnDefs) {
|
||||
r.push({
|
||||
input: createPostgresInput(resourceValue, tableValue, columnDefs, whereClause),
|
||||
@@ -672,6 +673,14 @@
|
||||
})
|
||||
},
|
||||
disabled: !savedApp
|
||||
},
|
||||
// App debug menu
|
||||
{
|
||||
displayName: 'Troubleshoot panel',
|
||||
icon: Bug,
|
||||
action: () => {
|
||||
debugAppDrawerOpen = true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -684,6 +693,10 @@
|
||||
let rightColumnSelect: 'timeline' | 'detail' = 'timeline'
|
||||
|
||||
let appReportingDrawerOpen = false
|
||||
|
||||
export function openTroubleshootPanel() {
|
||||
debugAppDrawerOpen = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
@@ -936,6 +949,12 @@
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<Drawer bind:open={debugAppDrawerOpen} size="800px">
|
||||
<DrawerContent title="Troubleshoot Panel" on:close={() => (debugAppDrawerOpen = false)}>
|
||||
<DebugPanel />
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<Drawer bind:open={$jobsDrawerOpen} size="900px" --zIndex={1003}>
|
||||
<DrawerContent
|
||||
noPadding
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
title="Custom Components"
|
||||
on:close={ccDrawer.closeDrawer}
|
||||
documentationLink="https://www.windmill.dev/docs/apps/react_components"
|
||||
>
|
||||
>
|
||||
<ComponentsList on:reload={fetchCustomComponents} />
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import { allItems } from '../../utils'
|
||||
import type { AppViewerContext } from '../../types'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import Badge from '$lib/components/common/badge/Badge.svelte'
|
||||
import { findGridItem } from '../appUtils'
|
||||
import { pluralize } from '$lib/utils'
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import { Trash } from 'lucide-svelte'
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
|
||||
const { app, initialized } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
$: unintitializedComponents = allItems($app.grid, $app.subgrids)
|
||||
.map((x) => x.id)
|
||||
.filter((x) => !$initialized.initializedComponents?.includes(x))
|
||||
.sort()
|
||||
|
||||
$: subgridsErrors = Object.keys($app.subgrids ?? {})
|
||||
.map((x) => {
|
||||
const parentId = x.split('-')[0]
|
||||
const parent = findGridItem($app, parentId)
|
||||
|
||||
if (parent === undefined) {
|
||||
return {
|
||||
subGridId: x,
|
||||
error: 'Parent not found'
|
||||
}
|
||||
} else if (parent?.data?.numberOfSubgrids === undefined) {
|
||||
return {
|
||||
subGridId: x,
|
||||
error: 'Parent is not a container'
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-8" style="all:none;">
|
||||
{#if unintitializedComponents?.length === 0 && subgridsErrors?.length === 0}
|
||||
<Alert type="success" title="No issues found">
|
||||
The app has no subgrid errors or uninitialized components.
|
||||
</Alert>
|
||||
{:else}
|
||||
<Alert type="error" title="Issues found">
|
||||
The app has {unintitializedComponents.length} uninitialized components and {subgridsErrors.length}
|
||||
subgrid errors.
|
||||
<br />
|
||||
Please contact Windmill support for assistance.
|
||||
</Alert>
|
||||
{/if}
|
||||
{#if unintitializedComponents.length > 0}
|
||||
<Section label="Uninitialized components">
|
||||
<div class="max-w-xl">
|
||||
<div class="text-sm mb-4">
|
||||
There are {pluralize(unintitializedComponents.length, 'uninitialized component')} in the app.
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 border rounded-md overflow-hidden">
|
||||
<!-- Header -->
|
||||
<div class="font-semibold bg-gray-100 dark:bg-gray-900 px-2 py-1 text-xs border-b"
|
||||
>Component Id</div
|
||||
>
|
||||
<div class="font-semibold bg-gray-100 dark:bg-gray-900 px-2 py-1 text-xs border-b"
|
||||
>Type</div
|
||||
>
|
||||
<div class="font-semibold bg-gray-100 dark:bg-gray-900 px-2 py-1 text-xs border-b"
|
||||
>Status</div
|
||||
>
|
||||
|
||||
<!-- Iterate over uninitializedComponents to display each component in the grid -->
|
||||
{#each unintitializedComponents as c}
|
||||
<!-- Component Id -->
|
||||
<div class="text-xs flex items-center px-2 py-2">
|
||||
<Badge>
|
||||
{c}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div class="text-xs flex items-center px-2 py-2">
|
||||
<Badge color="blue">
|
||||
{findGridItem($app, c)?.data?.type || 'Unknown'}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div class="text-xs flex items-center px-2 py-2">
|
||||
<Badge color="red">Uninitialized</Badge>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</Section>{/if}
|
||||
{#if subgridsErrors.length > 0}
|
||||
<Section label="Subgrids errors">
|
||||
<div class="max-w-xl">
|
||||
<div class="text-sm mb-4">
|
||||
There are
|
||||
{pluralize(subgridsErrors.length, 'subgrid')} with errors in the app.
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 border rounded-md overflow-hidden">
|
||||
<!-- Header -->
|
||||
<div class="font-semibold bg-gray-100 dark:bg-gray-900 px-2 py-1 text-xs border-b"
|
||||
>Subgrid Id</div
|
||||
>
|
||||
<div class="font-semibold bg-gray-100 dark:bg-gray-900 px-2 py-1 text-xs border-b"
|
||||
>Error</div
|
||||
>
|
||||
<div class="font-semibold bg-gray-100 dark:bg-gray-900 px-2 py-1 text-xs border-b"
|
||||
>Action</div
|
||||
>
|
||||
|
||||
<!-- Iterate over uninitializedComponents to display each component in the grid -->
|
||||
{#each subgridsErrors as s}
|
||||
<!-- Component Id -->
|
||||
<div class="text-xs flex items-center px-2 py-2">
|
||||
<Badge>
|
||||
{s?.subGridId}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div class="text-xs flex items-center px-2 py-2">
|
||||
<Badge color="red">
|
||||
{s?.error}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div class="text-xs flex items-center px-2 py-2">
|
||||
<Button
|
||||
color="light"
|
||||
startIcon={{
|
||||
icon: Trash
|
||||
}}
|
||||
size="xs2"
|
||||
on:click={() => {
|
||||
if ($app.subgrids && s) {
|
||||
delete $app.subgrids[s.subGridId]
|
||||
$app = { ...$app }
|
||||
}
|
||||
}}
|
||||
>
|
||||
Remove subgrid
|
||||
</Button>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
{/if}
|
||||
</div>
|
||||
Reference in New Issue
Block a user