add context to context panel in apps

This commit is contained in:
Ruben Fiszel
2023-01-03 10:41:51 +01:00
parent fa522da565
commit 976c3d49dd
8 changed files with 93 additions and 64 deletions
@@ -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} /> &nbsp; <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} /> &nbsp; <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}
+8 -2
View File
@@ -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}