From 0ffac69406e1cd068a172b528037bb396fe9e092 Mon Sep 17 00:00:00 2001 From: Faton Ramadani Date: Mon, 8 Jul 2024 13:23:28 +0200 Subject: [PATCH] feat(frontend): improve table actions (#4040) * feat(frontend): wip * feat(frontend): fix table actions width, hovering behavior and fixed connection * feat(frontend): support infinite list + Db Explorer --- .../table/AppAggridExplorerTable.svelte | 10 +- .../display/table/AppAggridTable.svelte | 10 +- .../table/AppAggridTableActions.svelte | 113 +++++++++++------- .../apps/editor/component/Component.svelte | 6 + .../flows/content/FlowEditorPanel.svelte | 4 +- 5 files changed, 94 insertions(+), 49 deletions(-) diff --git a/frontend/src/lib/components/apps/components/display/table/AppAggridExplorerTable.svelte b/frontend/src/lib/components/apps/components/display/table/AppAggridExplorerTable.svelte index 95d1ea636e..92b24d63c6 100644 --- a/frontend/src/lib/components/apps/components/display/table/AppAggridExplorerTable.svelte +++ b/frontend/src/lib/components/apps/components/display/table/AppAggridExplorerTable.svelte @@ -2,7 +2,7 @@ import { GridApi, createGrid, type IDatasource } from 'ag-grid-community' import { sendUserToast } from '$lib/utils' import { createEventDispatcher, getContext } from 'svelte' - import type { AppViewerContext, ComponentCustomCSS } from '../../../types' + import type { AppViewerContext, ComponentCustomCSS, ContextPanelContext } from '../../../types' import type { TableAction, components } from '$lib/components/apps/editor/component' import { deepEqual } from 'fast-equals' @@ -39,6 +39,7 @@ let inputs = {} const context = getContext('AppViewerContext') + const contextPanel = getContext('ContextPanel') const { app, selectedComponent, componentControl, darkMode } = context let css = initCss($app.css?.aggridcomponent, customCss) @@ -120,6 +121,11 @@ const rowIndex = p.node.rowIndex ?? 0 const row = p.data + const componentContext = new Map([ + ['AppViewerContext', context], + ['ContextPanel', contextPanel] + ]) + new AppAggridTableActions({ target: c.eGui, props: { @@ -155,7 +161,7 @@ outputs?.inputs.set(inputs, true) } }, - context: new Map([['AppViewerContext', context]]) + context: componentContext }) }) diff --git a/frontend/src/lib/components/apps/components/display/table/AppAggridTable.svelte b/frontend/src/lib/components/apps/components/display/table/AppAggridTable.svelte index b9e8c35e0e..0b3f7d70c7 100644 --- a/frontend/src/lib/components/apps/components/display/table/AppAggridTable.svelte +++ b/frontend/src/lib/components/apps/components/display/table/AppAggridTable.svelte @@ -6,6 +6,7 @@ import type { AppViewerContext, ComponentCustomCSS, + ContextPanelContext, ListContext, ListInputs, RichConfigurations @@ -50,7 +51,7 @@ export let actions: TableAction[] | undefined = undefined const context = getContext('AppViewerContext') - + const contextPanel = getContext('ContextPanel') const iterContext = getContext('ListWrapperContext') const listInputs: ListInputs | undefined = getContext('ListInputs') @@ -196,6 +197,11 @@ const rowIndex = p.node.rowIndex ?? 0 const row = p.data + const componentContext = new Map([ + ['AppViewerContext', context], + ['ContextPanel', contextPanel] + ]) + new AppAggridTableActions({ target: c.eGui, props: { @@ -231,7 +237,7 @@ outputs?.inputs.set(inputs, true) } }, - context: new Map([['AppViewerContext', context]]) + context: componentContext }) }) diff --git a/frontend/src/lib/components/apps/components/display/table/AppAggridTableActions.svelte b/frontend/src/lib/components/apps/components/display/table/AppAggridTableActions.svelte index 0112a8dcdd..0c60b3efc4 100644 --- a/frontend/src/lib/components/apps/components/display/table/AppAggridTableActions.svelte +++ b/frontend/src/lib/components/apps/components/display/table/AppAggridTableActions.svelte @@ -1,5 +1,5 @@ @@ -38,6 +50,7 @@ 'flex flex-row justify-center items-center gap-4 h-full px-4 py-1 w-full', wrapActions ? 'flex-wrap' : '' )} + bind:this={rowDiv} > {#each actions as action, actionIndex} @@ -56,13 +69,20 @@ }} on:pointerdown|stopPropagation={(e) => { selectRow() - $selectedComponent = [action.id] + + if (!$connectingInput.opened) { + $selectedComponent = [action.id] + } }} class={twMerge( ($selectedComponent?.includes(action.id) || $hoverStore === action.id) && $mode !== 'preview' - ? 'outline outline-indigo-500 outline-1 outline-offset-1 relative z-50' - : 'relative' + ? 'outline outline-indigo-500 outline-1 outline-offset-1 relative ' + : 'relative', + $hoverStore === action.id && $selectedComponent?.[0] !== action.id + ? 'outline-blue-500' + : '', + 'w-full cursor-pointer' )} > {#if $mode !== 'preview'} @@ -73,6 +93,9 @@ class={twMerge( 'px-2 text-2xs font-bold absolute shadow -top-2 -left-4 border z-50 rounded-sm w-8 !h-5 flex justify-center items-center', 'bg-indigo-500/90 border-indigo-600 text-white', + $hoverStore === action.id && $selectedComponent?.[0] !== action.id + ? 'bg-blue-500/90 border-blue-600' + : '', $selectedComponent?.includes(action.id) || $hoverStore === action.id ? 'opacity-100' : 'opacity-0' @@ -101,8 +124,16 @@ - connectOutput(connectingInput, 'buttoncomponent', action.id, detail)} + on:select={({ detail }) => { + const tableId = action.id.split('_')[0] + + connectOutput( + connectingInput, + action.type, + tableId, + `inputs.${action.id}[${rowIndex}].${detail}` + ) + }} componentId={action.id} /> @@ -171,25 +202,23 @@ {controls} /> {:else if action.type == 'selectcomponent'} -
- { - dispatch('toggleRow') - selectRow() - }} - {controls} - /> -
+ { + dispatch('toggleRow') + selectRow() + }} + {controls} + /> {/if} {:else if action.type == 'buttoncomponent'} {:else if action.type == 'selectcomponent'} -
- { - dispatch('toggleRow') - selectRow() - }} - /> -
+ { + dispatch('toggleRow') + selectRow() + }} + /> {/if} {/each} diff --git a/frontend/src/lib/components/apps/editor/component/Component.svelte b/frontend/src/lib/components/apps/editor/component/Component.svelte index ee11896b2d..488aef7bae 100644 --- a/frontend/src/lib/components/apps/editor/component/Component.svelte +++ b/frontend/src/lib/components/apps/editor/component/Component.svelte @@ -102,6 +102,12 @@ outTimeout && clearTimeout(outTimeout) outTimeout = setTimeout(() => { if ($hoverStore !== undefined) { + // In order to avoid flickering when hovering over table actions, + // we leave the actions to manage the hover state + if ($hoverStore.startsWith(`${component.id}_`)) { + return + } + $hoverStore = undefined } }, 50) diff --git a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte index 42a41833e4..85e864fd29 100644 --- a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte +++ b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte @@ -33,11 +33,11 @@ return } - if (!$flowStateStore) { + if (!$flowInputsStore) { $flowInputsStore = {} } - $flowInputsStore![module?.id] = { + $flowInputsStore[module?.id] = { requiredInputsFilled: initRequiredInputFilled( module.value, $flowStateStore?.[module?.id]?.schema ?? {}