fix: improve connection in apps

This commit is contained in:
Ruben Fiszel
2023-09-30 23:45:50 +02:00
parent 9f88809ee5
commit a2fca17ae2
7 changed files with 90 additions and 24 deletions

View File

@@ -2,7 +2,7 @@
import { UserService, GlobalUserInfo } from '$lib/gen'
import TableCustom from '$lib/components/TableCustom.svelte'
import InviteGlobalUser from '$lib/components/InviteGlobalUser.svelte'
import { Badge, Drawer, DrawerContent, Tab, Tabs } from '$lib/components/common'
import { Drawer, DrawerContent, Tab, Tabs } from '$lib/components/common'
import { sendUserToast } from '$lib/toast'
import SearchItems from './SearchItems.svelte'
import { page } from '$app/stores'

View File

@@ -28,12 +28,15 @@
import { components, type ButtonComponent } from '../../../editor/component'
import { initCss } from '../../../utils'
import { twMerge } from 'tailwind-merge'
import { initConfig, initOutput } from '$lib/components/apps/editor/appUtils'
import { connectOutput, initConfig, initOutput } from '$lib/components/apps/editor/appUtils'
import ResolveConfig from '../../helpers/ResolveConfig.svelte'
import AppCheckbox from '../../inputs/AppCheckbox.svelte'
import AppSelect from '../../inputs/AppSelect.svelte'
import RowWrapper from '../../layout/RowWrapper.svelte'
import ResolveStyle from '../../helpers/ResolveStyle.svelte'
import { Popup } from '$lib/components/common'
import ComponentOutputViewer from '$lib/components/apps/editor/contextPanel/ComponentOutputViewer.svelte'
import { Plug2 } from 'lucide-svelte'
export let id: string
export let componentInput: AppInput | undefined
@@ -50,8 +53,15 @@
let result: Record<string, any>[] | undefined = undefined
const { app, worldStore, componentControl, selectedComponent, hoverStore, mode } =
getContext<AppViewerContext>('AppViewerContext')
const {
app,
worldStore,
componentControl,
selectedComponent,
hoverStore,
mode,
connectingInput
} = getContext<AppViewerContext>('AppViewerContext')
let searchValue = ''
@@ -378,6 +388,7 @@
>
<div class="center-center h-full w-full flex-wrap gap-1.5">
{#each actionButtons as actionButton, actionIndex (actionButton?.id)}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<RowWrapper
bind:inputs
value={row.original}
@@ -403,11 +414,12 @@
$hoverStore === actionButton.id) &&
$mode !== 'preview'
? 'outline outline-indigo-500 outline-1 outline-offset-1 relative'
: ''
: 'relative'
)}
>
{#if $mode !== 'preview'}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<span
title={`Id: ${actionButton.id}`}
class={classNames(
@@ -424,6 +436,35 @@
>
{actionButton.id}
</span>
{#if $connectingInput.opened}
<div class="absolute z-50 left-8 -top-[10px]">
<Popup
floatingConfig={{
strategy: 'absolute',
placement: 'bottom-start'
}}
>
<svelte:fragment slot="button">
<button
class="bg-red-500/70 border border-red-600 px-1 py-0.5"
title="Outputs"
aria-label="Open output"><Plug2 size={12} /></button
>
</svelte:fragment>
<ComponentOutputViewer
on:select={({ detail }) =>
connectOutput(
connectingInput,
'buttoncomponent',
actionButton.id,
detail
)}
componentId={actionButton.id}
/>
</Popup>
</div>
{/if}
{/if}
{#if rowIndex == 0}
{@const controls = {

View File

@@ -1,15 +1,16 @@
<script lang="ts">
import { classNames } from '$lib/utils'
import type { AppViewerContext } from '../types'
import { Anchor, Bug, Expand, Move, Pen } from 'lucide-svelte'
import { Anchor, Bug, Expand, Move, Pen, Plug2 } from 'lucide-svelte'
import { createEventDispatcher, getContext } from 'svelte'
import Popover from '$lib/components/Popover.svelte'
import { Alert, Button } from '$lib/components/common'
import { Alert, Button, Popup } from '$lib/components/common'
import type { AppComponent } from './component'
import { twMerge } from 'tailwind-merge'
import { getErrorFromLatestResult } from './appUtils'
import { connectOutput, getErrorFromLatestResult } from './appUtils'
import TabsDebug from './TabsDebug.svelte'
import ComponentOutputViewer from './contextPanel/ComponentOutputViewer.svelte'
export let component: AppComponent
export let selected: boolean
@@ -34,8 +35,28 @@
}
</script>
{#if connecting}
<div class="absolute z-50 left-6 -top-[11px]">
<Popup floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}>
<svelte:fragment slot="button">
<button
class="bg-red-500/70 border border-red-600 px-1 py-0.5"
title="Outputs"
aria-label="Open output"><Plug2 size={12} /></button
>
</svelte:fragment>
<ComponentOutputViewer
on:select={({ detail }) =>
connectOutput(connectingInput, component.type, component.id, detail)}
componentId={component.id}
/>
</Popup>
</div>
{/if}
{#if selected || hover}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<span
on:mouseover|stopPropagation={() => {
dispatch('mouseover')

View File

@@ -3,6 +3,7 @@
import { getContext } from 'svelte'
import type { AppViewerContext } from '../types'
import { secondaryMenuRight } from './settingsPanel/secondaryMenu'
import { Plug2 } from 'lucide-svelte'
const { connectingInput } = getContext<AppViewerContext>('AppViewerContext')
@@ -17,13 +18,13 @@
<div class="m-2">
<Alert title="Connecting" type="info">
<div class="flex gap-2 flex-col">
Click on the output of the component you want to connect to on the left panel.
<div class="my-2">
<ol class="list-disc flex gap-2 flex-col">
<li> App is in a frozen state. </li>
<li> Clicking on a component will open the component's output on the left. </li>
<li> Hover on a component to see its output</li>
</ol>
<div>
Click on the output of the component you want to connect to on the left panel 'Outputs' or
in the popup by clicking the <span
><div class="inline-flex"
><div class="bg-red-500/90 border-red-600 px-1 py-0.5"><Plug2 size={12} /></div></div
></span
>
</div>
<div>
<Button color="blue" variant="border" size="xs" on:click={stopConnecting}>

View File

@@ -104,6 +104,15 @@ export function selectId(
}
}
export function connectOutput(connectingInput: Writable<ConnectingInput>, typ: TypedComponent['type'], id: string, spath: string) {
if (get(connectingInput).opened) {
let splitted = spath?.split('.')
let componentId = typ == 'containercomponent' ? splitted?.[0] : id
let path = typ == 'containercomponent' ? splitted?.[1] : spath
connectingInput.set(connectInput(get(connectingInput), componentId, path, typ))
}
}
function findGridItemById(
root: GridItem[],
subGrids: Record<string, GridItem[]> | undefined,

View File

@@ -20,7 +20,7 @@
// Prevent interaction with the component when connecting an input
// We let the event bubble up if the component is a container, so we can select a tab for example
function preventInteraction(event: Event, isContainer: boolean = false) {
if ($connectingInput.opened && !isContainer) {
if ($connectingInput.opened && !isContainer && event.type != 'click') {
event.stopPropagation()
}
}

View File

@@ -3,7 +3,7 @@
import { getContext } from 'svelte'
import type { AppViewerContext, GridItem } from '../../types'
import ComponentOutputViewer from './ComponentOutputViewer.svelte'
import { connectInput } from '../appUtils'
import { connectOutput } from '../appUtils'
import SubGridOutput from './SubGridOutput.svelte'
import OutputHeader from './components/OutputHeader.svelte'
import TableActionsOutput from './components/TableActionsOutput.svelte'
@@ -38,13 +38,7 @@
<ComponentOutputViewer
componentId={gridItem.id}
on:select={({ detail }) => {
if ($connectingInput.opened) {
let typ = gridItem?.data?.type
let splitted = detail?.split('.')
let componentId = typ == 'containercomponent' ? splitted?.[0] : gridItem.id
let path = typ == 'containercomponent' ? splitted?.[1] : detail
$connectingInput = connectInput($connectingInput, componentId, path, typ)
}
connectOutput(connectingInput, gridItem?.data?.type, gridItem.data.id, detail)
}}
/>