mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 16:09:39 +00:00
add context to context panel in apps
This commit is contained in:
@@ -86,7 +86,9 @@
|
||||
mounted = true
|
||||
})
|
||||
|
||||
$: mounted && ($worldStore = buildWorld($staticOutputs, $worldStore))
|
||||
$: context = { email: $userStore?.email, username: $userStore?.username }
|
||||
|
||||
$: mounted && ($worldStore = buildWorld($staticOutputs, $worldStore, context))
|
||||
$: previewing = $mode === 'preview'
|
||||
$: width = $breakpoint === 'sm' ? 'min-w-[400px] max-w-[656px]' : 'min-w-[710px] w-full'
|
||||
|
||||
@@ -118,6 +120,7 @@
|
||||
{breakpoint}
|
||||
{policy}
|
||||
isEditor
|
||||
{context}
|
||||
/>
|
||||
{:else}
|
||||
<SplitPanesWrapper class="max-w-full overflow-hidden">
|
||||
|
||||
@@ -218,11 +218,13 @@
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
<div class="border-b flex flex-row justify-between py-1 gap-4 flex-wrap gap-y-2 px-4 items-center">
|
||||
<div class="w-64">
|
||||
<div
|
||||
class="border-b flex flex-row justify-between py-1 gap-4 overflow-x-auto gap-y-2 px-4 items-center"
|
||||
>
|
||||
<div class="min-w-64 w-64">
|
||||
<input type="text" placeholder="App summary" class="text-sm w-full" bind:value={$summary} />
|
||||
</div>
|
||||
<div class="flex gap-8 items-center grow justify-center">
|
||||
<div class="flex gap-4 items-center grow justify-center">
|
||||
<div>
|
||||
<ToggleButtonGroup bind:selected={$mode}>
|
||||
<ToggleButton position="left" value="dnd" size="xs">
|
||||
@@ -245,18 +247,22 @@
|
||||
</ToggleButtonGroup>
|
||||
</div>
|
||||
|
||||
<ToggleButtonGroup bind:selected={$app.fullscreen}>
|
||||
<ToggleButton position="left" value={false} size="xs"
|
||||
><AlignHorizontalSpaceAround size={14} /> <Tooltip
|
||||
>The max width is 1168px and the content stay centered instead of taking the full page
|
||||
width</Tooltip
|
||||
></ToggleButton
|
||||
>
|
||||
<ToggleButton position="right" value={true} size="xs"><Expand size={14} /></ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
<span class="hidden lg:block">
|
||||
<ToggleButtonGroup bind:selected={$app.fullscreen}>
|
||||
<ToggleButton position="left" value={false} size="xs"
|
||||
><AlignHorizontalSpaceAround size={14} /> <Tooltip
|
||||
>The max width is 1168px and the content stay centered instead of taking the full page
|
||||
width</Tooltip
|
||||
></ToggleButton
|
||||
>
|
||||
<ToggleButton position="right" value={true} size="xs"><Expand size={14} /></ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-row grow gap-4 justify-end ">
|
||||
<AppExportButton app={$app} />
|
||||
<span class="hidden lg:block">
|
||||
<AppExportButton app={$app} />
|
||||
</span>
|
||||
|
||||
<Button
|
||||
on:click={() => (publishDrawerOpen = true)}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
export let summary: string
|
||||
export let workspace: string
|
||||
export let isEditor: boolean
|
||||
export let context: Record<string, any>
|
||||
|
||||
const appStore = writable<App>(app)
|
||||
const worldStore = writable<World | undefined>(undefined)
|
||||
@@ -60,7 +61,7 @@
|
||||
mounted = true
|
||||
})
|
||||
|
||||
$: mounted && ($worldStore = buildWorld($staticOutputs, undefined))
|
||||
$: mounted && ($worldStore = buildWorld($staticOutputs, undefined, context))
|
||||
$: width = $breakpoint === 'sm' ? 'max-w-[640px]' : 'w-full '
|
||||
</script>
|
||||
|
||||
|
||||
@@ -30,63 +30,72 @@
|
||||
|
||||
if (component?.data.type) {
|
||||
return displayData[component?.data.type].name
|
||||
} else if (componentId == 'context') {
|
||||
return 'Context'
|
||||
} else {
|
||||
return 'Table action'
|
||||
}
|
||||
}
|
||||
$: panels = [['context', ['email', 'username']] as [string, string[]]].concat(
|
||||
Object.entries($staticOutputs)
|
||||
)
|
||||
</script>
|
||||
|
||||
<PanelSection noPadding titlePadding="px-4 pt-2" title="Outputs">
|
||||
<div class="overflow-auto min-w-[150px] border-t w-full relative flex flex-col gap-2 px-4 pb-2">
|
||||
{#each Object.entries($staticOutputs) as [componentId, outputs] (componentId)}
|
||||
<div
|
||||
class="overflow-auto min-w-[150px] border-t w-full relative flex flex-col gap-4 px-4 pt-4 pb-2"
|
||||
>
|
||||
{#each panels as [componentId, outputs] (componentId)}
|
||||
{#if outputs.length > 0 && $worldStore?.outputsById[componentId]}
|
||||
<div
|
||||
class="flex {$connectingInput?.opened
|
||||
? 'bg-white z-50'
|
||||
: ''} flex-row justify-between w-full -mb-2"
|
||||
>
|
||||
<button
|
||||
on:click|stopPropagation|preventDefault={$connectingInput.opened
|
||||
? undefined
|
||||
: () => ($selectedComponent = componentId)}
|
||||
class={classNames(
|
||||
'px-2 text-2xs py-0.5 font-bold rounded-t-sm w-fit',
|
||||
$selectedComponent === componentId
|
||||
? ' bg-indigo-500 text-white'
|
||||
: 'bg-gray-200 text-gray-500'
|
||||
)}
|
||||
<div>
|
||||
<div
|
||||
class="flex {$connectingInput?.opened
|
||||
? 'bg-white z-50'
|
||||
: ''} flex-row justify-between w-full"
|
||||
>
|
||||
{componentId}
|
||||
</button>
|
||||
<span
|
||||
class={classNames(
|
||||
'px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit',
|
||||
'bg-gray-500 text-white'
|
||||
)}
|
||||
>
|
||||
{getComponentNameById(componentId)}
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
on:click|stopPropagation|preventDefault={$connectingInput.opened
|
||||
? undefined
|
||||
: () => ($selectedComponent = componentId)}
|
||||
class={classNames(
|
||||
'px-2 text-2xs py-0.5 font-bold rounded-t-sm w-fit',
|
||||
$selectedComponent === componentId
|
||||
? ' bg-indigo-500 text-white'
|
||||
: 'bg-gray-200 text-gray-500'
|
||||
)}
|
||||
>
|
||||
{componentId}
|
||||
</button>
|
||||
<span
|
||||
class={classNames(
|
||||
'px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit',
|
||||
'bg-gray-500 text-white'
|
||||
)}
|
||||
>
|
||||
{getComponentNameById(componentId)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class={classNames(
|
||||
$connectingInput?.opened ? 'bg-white z-50' : '',
|
||||
`w-full py-2 border relative overflow-auto`,
|
||||
$selectedComponent === componentId ? 'border border-blue-500 ' : '',
|
||||
$connectingInput.hoveredComponent === componentId ? 'outline outline-blue-500' : ''
|
||||
)}
|
||||
>
|
||||
<!-- {#if $selectedComponent === componentId && $connectingInput?.opened}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class={classNames(
|
||||
$connectingInput?.opened ? 'bg-white z-50' : '',
|
||||
`w-full py-2 grow border relative overflow-x-auto`,
|
||||
$selectedComponent === componentId ? 'border border-blue-500 ' : '',
|
||||
$connectingInput.hoveredComponent === componentId ? 'outline outline-blue-500' : ''
|
||||
)}
|
||||
>
|
||||
<!-- {#if $selectedComponent === componentId && $connectingInput?.opened}
|
||||
<div class="absolute top-0 left-0 w-full h-full bg-gray-500 bg-opacity-50 z-10" />
|
||||
{/if} -->
|
||||
<ComponentOutputViewer
|
||||
{outputs}
|
||||
{componentId}
|
||||
on:select={({ detail }) => {
|
||||
connectInput(componentId, detail)
|
||||
}}
|
||||
/>
|
||||
<ComponentOutputViewer
|
||||
{outputs}
|
||||
{componentId}
|
||||
on:select={({ detail }) => {
|
||||
connectInput(componentId, detail)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
@@ -25,11 +25,17 @@ export type World = {
|
||||
|
||||
export function buildWorld(
|
||||
components: Record<string, string[]>,
|
||||
previousWorld: World | undefined
|
||||
previousWorld: World | undefined,
|
||||
context: Record<string, any>
|
||||
): World {
|
||||
const newWorld = buildObservableWorld()
|
||||
const outputsById: Record<string, Record<string, Output<any>>> = {}
|
||||
const state = writable(0)
|
||||
|
||||
const outputsById: Record<string, Record<string, Output<any>>> = {
|
||||
context: Object.fromEntries(Object.entries(context).map(([k, v]) => {
|
||||
return [k, newWorld.newOutput('context', k, state, v)]
|
||||
}))
|
||||
}
|
||||
for (const [k, outputs] of Object.entries(components)) {
|
||||
outputsById[k] = {}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import AppEditor from '$lib/components/apps/editor/AppEditor.svelte'
|
||||
import { AppService, AppWithLastVersion } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { page } from '$app/stores'
|
||||
import { decodeState } from '$lib/utils'
|
||||
import { goto } from '$app/navigation'
|
||||
@@ -17,6 +17,7 @@
|
||||
}
|
||||
|
||||
let loading = true
|
||||
|
||||
async function loadApp(): Promise<void> {
|
||||
loading = true
|
||||
app = await AppService.getAppByPath({
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Skeleton } from '$lib/components/common'
|
||||
import { AppService, AppWithLastVersion } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
let app: AppWithLastVersion | undefined = undefined
|
||||
@@ -24,6 +24,7 @@
|
||||
{#if app}
|
||||
<div class="border rounded-md p-2 w-full">
|
||||
<AppPreview
|
||||
context={{ email: $userStore?.email, username: $userStore?.username }}
|
||||
workspace={$workspaceStore ?? ''}
|
||||
summary={app.summary}
|
||||
app={app.value}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { Alert, Skeleton } from '$lib/components/common'
|
||||
import { WindmillIcon } from '$lib/components/icons'
|
||||
import { AppService, AppWithLastVersion, GlobalUserInfo, UserService } from '$lib/gen'
|
||||
import { userStore } from '$lib/stores'
|
||||
import github from 'svelte-highlight/styles/github'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
@@ -67,6 +68,7 @@
|
||||
{:else if app}
|
||||
<div class="border rounded-md p-2 w-full">
|
||||
<AppPreview
|
||||
context={{ email: $userStore?.email, username: $userStore?.username }}
|
||||
workspace={$page.params.workspace}
|
||||
summary={app.summary}
|
||||
app={app.value}
|
||||
|
||||
Reference in New Issue
Block a user