From 12def5ccca8497f41d238c4eebdd85e6e3571b71 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Mon, 19 Jun 2023 20:47:04 +0200 Subject: [PATCH] feat: list component for apps (#1740) * all * feat: list component for apps --- .../apps/components/buttons/AppButton.svelte | 4 +- .../apps/components/helpers/InputValue.svelte | 9 ++- .../helpers/RunnableComponent.svelte | 5 +- .../apps/components/layout/AppList.svelte | 79 +++++++++++++------ .../apps/components/layout/ListWrapper.svelte | 6 +- .../components/apps/editor/AppEditor.svelte | 2 +- .../apps/editor/SubGridEditor.svelte | 5 +- .../apps/editor/component/Component.svelte | 1 - .../apps/editor/component/components.ts | 33 +++++--- .../components/apps/editor/component/sets.ts | 2 +- .../componentsPanel/quickStyleProperties.ts | 3 + .../shared/ScriptRunConfiguration.svelte | 4 +- frontend/src/lib/components/apps/types.ts | 4 +- frontend/src/lib/components/apps/utils.ts | 1 + 14 files changed, 104 insertions(+), 54 deletions(-) diff --git a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte index 1e2d83fc80..d9636d9f25 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte @@ -147,8 +147,8 @@ {#if resolvedConfig.beforeIcon && beforeIconComponent} {/if} - {#if resolvedConfig.label && resolvedConfig.label?.length > 0} -
{resolvedConfig.label}
+ {#if resolvedConfig.label?.toString() && resolvedConfig.label?.toString()?.length > 0} +
{resolvedConfig.label.toString()}
{/if} {#if resolvedConfig.afterIcon && afterIconComponent} diff --git a/frontend/src/lib/components/apps/components/helpers/InputValue.svelte b/frontend/src/lib/components/apps/components/helpers/InputValue.svelte index bc4e67c3b1..23d44c3ced 100644 --- a/frontend/src/lib/components/apps/components/helpers/InputValue.svelte +++ b/frontend/src/lib/components/apps/components/helpers/InputValue.svelte @@ -2,7 +2,7 @@ import { isCodeInjection } from '$lib/components/flows/utils' import { createEventDispatcher, getContext, onDestroy, tick } from 'svelte' import type { AppInput, EvalAppInput, UploadAppInput } from '../../inputType' - import type { AppViewerContext, RichConfiguration } from '../../types' + import type { AppViewerContext, ListContext, RichConfiguration } from '../../types' import { accessPropertyByPath } from '../../utils' import { computeGlobalContext, eval_like } from './eval' import deepEqualWithOrderedArray from './deepEqualWithOrderedArray' @@ -19,6 +19,9 @@ const { componentControl, runnableComponents } = getContext('AppViewerContext') + const iterContext = getContext('ListWrapperContext') + + $: fullContext = iterContext ? { ...extraContext, iter: $iterContext } : extraContext const dispatch = createEventDispatcher() if (input == undefined) { @@ -116,7 +119,7 @@ try { const r = await eval_like( input.expr, - computeGlobalContext($worldStore, extraContext), + computeGlobalContext($worldStore, fullContext), true, $state, $mode == 'dnd', @@ -138,7 +141,7 @@ try { const r = await eval_like( '`' + input.eval + '`', - computeGlobalContext($worldStore, extraContext), + computeGlobalContext($worldStore, fullContext), true, $state, $mode == 'dnd', diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte index ef23642fd2..a7024a529a 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableComponent.svelte @@ -10,7 +10,7 @@ import { createEventDispatcher, getContext, onDestroy, onMount } from 'svelte' import type { AppInputs, Runnable } from '../../inputType' import type { Output } from '../../rx' - import type { AppViewerContext, CancelablePromise, InlineScript } from '../../types' + import type { AppViewerContext, CancelablePromise, InlineScript, ListContext } from '../../types' import { computeGlobalContext, eval_like } from './eval' import InputValue from './InputValue.svelte' import RefreshButton from './RefreshButton.svelte' @@ -57,6 +57,7 @@ app, connectingInput } = getContext('AppViewerContext') + const iterContext = getContext('ListWrapperContext') const dispatch = createEventDispatcher() @@ -165,7 +166,7 @@ try { const r = await eval_like( runnable.inlineScript?.content, - computeGlobalContext($worldStore, {}), + computeGlobalContext($worldStore, iterContext ? { iter: $iterContext } : {}), false, $state, $mode == 'dnd', diff --git a/frontend/src/lib/components/apps/components/layout/AppList.svelte b/frontend/src/lib/components/apps/components/layout/AppList.svelte index 9dda380d8a..c38414c90f 100644 --- a/frontend/src/lib/components/apps/components/layout/AppList.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppList.svelte @@ -12,7 +12,6 @@ import RunnableWrapper from '../helpers/RunnableWrapper.svelte' export let id: string - export let componentContainerHeight: number export let componentInput: AppInput | undefined export let configuration: RichConfigurations export let customCss: ComponentCustomCSS<'containercomponent'> | undefined = undefined @@ -41,6 +40,8 @@ $: css = concatCustomCss($app.css?.containercomponent, customCss) let result: any[] | undefined = undefined + + $: isCard = resolvedConfig.width?.selected == 'card' {#each Object.keys(components['listcomponent'].initialData.configuration) as key (key)} @@ -53,33 +54,59 @@ {/each} + -
+
{#if $app.subgrids?.[`${id}-0`]} - {#each result ?? [] as value, index} -
- - { - if (!$connectingInput.opened) { - $selectedComponent = [id] - } - onFocus() - }} - /> - -
- {/each} + {#if Array.isArray(result)} + {#each result ?? [] as value, index} +
+ + { + if (!$connectingInput.opened) { + $selectedComponent = [id] + } + onFocus() + }} + /> + +
+ {/each} + {:else} + + { + if (!$connectingInput.opened) { + $selectedComponent = [id] + } + onFocus() + }} + /> + +
Input data is not an array
+ {/if} {/if}
diff --git a/frontend/src/lib/components/apps/components/layout/ListWrapper.svelte b/frontend/src/lib/components/apps/components/layout/ListWrapper.svelte index 38cf6376e4..cebd328a04 100644 --- a/frontend/src/lib/components/apps/components/layout/ListWrapper.svelte +++ b/frontend/src/lib/components/apps/components/layout/ListWrapper.svelte @@ -1,11 +1,15 @@ diff --git a/frontend/src/lib/components/apps/editor/AppEditor.svelte b/frontend/src/lib/components/apps/editor/AppEditor.svelte index 8ee63b35ce..a85a9a80fd 100644 --- a/frontend/src/lib/components/apps/editor/AppEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditor.svelte @@ -150,7 +150,7 @@ if (befSelected) { if (!['ctx', 'state'].includes(befSelected) && !befSelected?.startsWith(BG_PREFIX)) { let item = findGridItem($appStore, befSelected) - if (item?.data.type === 'containercomponent') { + if (item?.data.type === 'containercomponent' || item?.data.type === 'listcomponent') { $focusedGrid = { parentComponentId: befSelected, subGridIndex: 0 diff --git a/frontend/src/lib/components/apps/editor/SubGridEditor.svelte b/frontend/src/lib/components/apps/editor/SubGridEditor.svelte index bae0054e07..6aea124b69 100644 --- a/frontend/src/lib/components/apps/editor/SubGridEditor.svelte +++ b/frontend/src/lib/components/apps/editor/SubGridEditor.svelte @@ -22,7 +22,6 @@ export let visible: boolean = true export let id: string export let shouldHighlight: boolean = true - export let forceView = false const dispatch = createEventDispatcher() @@ -76,9 +75,9 @@ classes ?? '', noPadding ? 'px-0' : 'px-2' )} - style="{containerHeight ? `height: ${containerHeight}px;` : ''} {style ?? ''}" + style="{containerHeight ? `height: ${containerHeight - 2}px;` : ''} {style ?? ''}" > - {#if $mode !== 'preview' || forceView} + {#if $mode !== 'preview'}
diff --git a/frontend/src/lib/components/apps/editor/component/Component.svelte b/frontend/src/lib/components/apps/editor/component/Component.svelte index 8e9a513fd9..308d70c4e4 100644 --- a/frontend/src/lib/components/apps/editor/component/Component.svelte +++ b/frontend/src/lib/components/apps/editor/component/Component.svelte @@ -460,7 +460,6 @@ customCss={component.customCss} configuration={component.configuration} componentInput={component.componentInput} - {componentContainerHeight} {render} bind:initializing /> diff --git a/frontend/src/lib/components/apps/editor/component/components.ts b/frontend/src/lib/components/apps/editor/component/components.ts index 2ea56df87b..0e8c751d5d 100644 --- a/frontend/src/lib/components/apps/editor/component/components.ts +++ b/frontend/src/lib/components/apps/editor/component/components.ts @@ -475,24 +475,37 @@ export const components = { listcomponent: { name: 'List', icon: ListIcon, - dims: '2:8-6:8' as AppComponentDimensions, + dims: '3:8-12:8' as AppComponentDimensions, customCss: { container: { class: '', style: '' } }, initialData: { configuration: { - minWidthPx: { + width: { + type: 'oneOf', + selected: 'card', + labels: { + card: 'Card', + row: 'Full Row' + }, + configuration: { + card: { + minWidthPx: { + type: 'static', + fieldType: 'number', + value: 300, + tooltip: 'Min Width in pixels' + } + }, + row: {} + } + } as const, + heightPx: { type: 'static', fieldType: 'number', - value: 300, - tooltip: 'Min Width in pixels' - }, - maxHeightPx: { - type: 'static', - fieldType: 'number', - value: 300, - tooltip: 'Max Height in pixels' + value: 280, + tooltip: 'Height in pixels' } }, componentInput: { diff --git a/frontend/src/lib/components/apps/editor/component/sets.ts b/frontend/src/lib/components/apps/editor/component/sets.ts index 32548294ab..188915286e 100644 --- a/frontend/src/lib/components/apps/editor/component/sets.ts +++ b/frontend/src/lib/components/apps/editor/component/sets.ts @@ -10,7 +10,7 @@ const layout: ComponentSet = { title: 'Layout', components: [ 'containercomponent', - // 'listcomponent', + 'listcomponent', 'horizontaldividercomponent', 'verticaldividercomponent', 'drawercomponent', diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts b/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts index 7c82d8c3f4..abbc3b34bf 100644 --- a/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts +++ b/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts @@ -659,6 +659,9 @@ export const quickStyleProperties: Record< containercomponent: { container: containerDefaultProps }, + listcomponent: { + container: containerDefaultProps + }, dateinputcomponent: { input: inputDefaultProps }, diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/script/shared/ScriptRunConfiguration.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/script/shared/ScriptRunConfiguration.svelte index bb4dbed9a9..9564d3750e 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/script/shared/ScriptRunConfiguration.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/script/shared/ScriptRunConfiguration.svelte @@ -16,8 +16,8 @@
{#if autoRefresh !== undefined && canConfigureRunOnStart} -
-
+
+
Run on start and app refresh You may want to disable this so that the background runnable is only triggered by diff --git a/frontend/src/lib/components/apps/types.ts b/frontend/src/lib/components/apps/types.ts index 4941a99d7b..933d18f755 100644 --- a/frontend/src/lib/components/apps/types.ts +++ b/frontend/src/lib/components/apps/types.ts @@ -150,10 +150,10 @@ export interface CancelablePromise extends Promise { cancel: () => void } -export type ListContext = { +export type ListContext = Writable<{ index: number value: any -} +}> export type AppViewerContext = { worldStore: Writable diff --git a/frontend/src/lib/components/apps/utils.ts b/frontend/src/lib/components/apps/utils.ts index a5a8c06355..eda6378c8e 100644 --- a/frontend/src/lib/components/apps/utils.ts +++ b/frontend/src/lib/components/apps/utils.ts @@ -222,6 +222,7 @@ declare function setSelectedIndex(id: string, index: number): void; : '' } declare const state: ${JSON.stringify(state)}; +declare const iter: {index: number, value: any}; ` }