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
This commit is contained in:
Faton Ramadani
2024-07-08 13:23:28 +02:00
committed by GitHub
parent 11b05b3d17
commit 0ffac69406
5 changed files with 94 additions and 49 deletions
@@ -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>('AppViewerContext')
const contextPanel = getContext<ContextPanelContext>('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<string, any>([
['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
})
})
@@ -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>('AppViewerContext')
const contextPanel = getContext<ContextPanelContext>('ContextPanel')
const iterContext = getContext<ListContext>('ListWrapperContext')
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
@@ -196,6 +197,11 @@
const rowIndex = p.node.rowIndex ?? 0
const row = p.data
const componentContext = new Map<string, any>([
['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
})
})
@@ -1,5 +1,5 @@
<script lang="ts">
import { createEventDispatcher, getContext } from 'svelte'
import { createEventDispatcher, getContext, onMount } from 'svelte'
import type { AppViewerContext } from '../../../types'
import type { TableAction } from '$lib/components/apps/editor/component'
@@ -30,6 +30,18 @@
const dispatch = createEventDispatcher()
const { selectedComponent, hoverStore, mode, connectingInput } =
getContext<AppViewerContext>('AppViewerContext')
let rowDiv: HTMLDivElement | undefined = undefined
onMount(() => {
// apply w-full to the the parent of the parent of the rowDiv
if (rowDiv) {
const parent = rowDiv.parentElement?.parentElement?.parentElement
if (parent) {
parent.classList.add('w-full')
}
}
})
</script>
<RowWrapper value={row} index={rowIndex} {onSet} {onRemove}>
@@ -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}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
@@ -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 @@
</svelte:fragment>
<ComponentOutputViewer
suffix="table"
on:select={({ detail }) =>
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}
/>
</Popup>
@@ -171,25 +202,23 @@
{controls}
/>
{:else if action.type == 'selectcomponent'}
<div class="w-40">
<AppSelect
noDefault
noInitialize
extraKey={'idx' + rowIndex}
{render}
--font-size="10px"
id={action.id}
customCss={action.customCss}
configuration={action.configuration}
recomputeIds={action.recomputeIds}
onSelect={action.onSelect}
preclickAction={async () => {
dispatch('toggleRow')
selectRow()
}}
{controls}
/>
</div>
<AppSelect
noDefault
noInitialize
extraKey={'idx' + rowIndex}
{render}
--font-size="10px"
id={action.id}
customCss={action.customCss}
configuration={action.configuration}
recomputeIds={action.recomputeIds}
onSelect={action.onSelect}
preclickAction={async () => {
dispatch('toggleRow')
selectRow()
}}
{controls}
/>
{/if}
{:else if action.type == 'buttoncomponent'}
<AppButton
@@ -227,24 +256,22 @@
}}
/>
{:else if action.type == 'selectcomponent'}
<div class="w-40">
<AppSelect
noDefault
noInitialize
extraKey={'idx' + rowIndex}
{render}
--font-size="10px"
id={action.id}
customCss={action.customCss}
configuration={action.configuration}
recomputeIds={action.recomputeIds}
onSelect={action.onSelect}
preclickAction={async () => {
dispatch('toggleRow')
selectRow()
}}
/>
</div>
<AppSelect
noDefault
noInitialize
extraKey={'idx' + rowIndex}
{render}
--font-size="10px"
id={action.id}
customCss={action.customCss}
configuration={action.configuration}
recomputeIds={action.recomputeIds}
onSelect={action.onSelect}
preclickAction={async () => {
dispatch('toggleRow')
selectRow()
}}
/>
{/if}
</div>
{/each}
@@ -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)
@@ -33,11 +33,11 @@
return
}
if (!$flowStateStore) {
if (!$flowInputsStore) {
$flowInputsStore = {}
}
$flowInputsStore![module?.id] = {
$flowInputsStore[module?.id] = {
requiredInputsFilled: initRequiredInputFilled(
module.value,
$flowStateStore?.[module?.id]?.schema ?? {}