mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 00:02:19 +00:00
improve load time for text and button components
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
export let preclickAction: (() => Promise<void>) | undefined = undefined
|
||||
export let customCss: ComponentCustomCSS<'buttoncomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
export let initializing: boolean | undefined = true
|
||||
export let initializing: boolean | undefined = false
|
||||
export let extraKey: string | undefined = undefined
|
||||
|
||||
export let controls: { left: () => boolean; right: () => boolean | string } | undefined =
|
||||
@@ -31,6 +31,12 @@
|
||||
|
||||
const { worldStore, app, componentControl, selectedComponent } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
let resolvedConfig = initConfig(
|
||||
components['buttoncomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
$: initializing = resolvedConfig?.label == undefined
|
||||
|
||||
let outputs = initOutput($worldStore, id, {
|
||||
result: undefined,
|
||||
@@ -46,10 +52,6 @@
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
|
||||
let resolvedConfig = initConfig(components['buttoncomponent'].initialData.configuration)
|
||||
|
||||
$: initializing = resolvedConfig?.label == undefined
|
||||
|
||||
let beforeIconComponent: any
|
||||
let afterIconComponent: any
|
||||
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
loading: false
|
||||
})
|
||||
|
||||
let resolvedConfig = initConfig(components['formcomponent'].initialData.configuration)
|
||||
let resolvedConfig = initConfig(
|
||||
components['formcomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
let runnableComponent: RunnableComponent
|
||||
|
||||
let isLoading: boolean = false
|
||||
|
||||
@@ -34,7 +34,10 @@
|
||||
loading: false
|
||||
})
|
||||
|
||||
let resolvedConfig = initConfig(components['formbuttoncomponent'].initialData.configuration)
|
||||
let resolvedConfig = initConfig(
|
||||
components['formbuttoncomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
let runnableComponent: RunnableComponent
|
||||
|
||||
let isLoading: boolean = false
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
export let customCss: ComponentCustomCSS<'imagecomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
components['imagecomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
const { app, worldStore } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const fit: Record<string, string> = {
|
||||
cover: 'object-cover',
|
||||
@@ -23,8 +28,6 @@
|
||||
//used so that we can count number of outputs setup for first refresh
|
||||
initOutput($worldStore, id, {})
|
||||
|
||||
let resolvedConfig = initConfig(components['imagecomponent'].initialData.configuration)
|
||||
|
||||
$: css = concatCustomCss($app.css?.imagecomponent, customCss)
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
import { copyToClipboard } from '../../../../utils'
|
||||
import Button from '../../../common/button/Button.svelte'
|
||||
import Popover from '../../../Popover.svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { AppInput, EvalAppInput } from '../../inputType'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import type {
|
||||
@@ -15,9 +14,12 @@
|
||||
RichConfigurations
|
||||
} from '../../types'
|
||||
import { getContext } from 'svelte'
|
||||
import { initOutput } from '../../editor/appUtils'
|
||||
import { initConfig, initOutput } from '../../editor/appUtils'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { get } from 'svelte/store'
|
||||
import ResolveConfig from '../helpers/ResolveConfig.svelte'
|
||||
import { components } from '../../editor/component'
|
||||
import { isCodeInjection } from '$lib/components/flows/utils'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
@@ -28,22 +30,29 @@
|
||||
export let customCss: ComponentCustomCSS<'textcomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
components['textcomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
const { app, worldStore, mode } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const editorcontext = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
let result: string | undefined = undefined
|
||||
|
||||
if (componentInput?.type == 'template' && !isCodeInjection(componentInput.eval)) {
|
||||
result = componentInput.eval
|
||||
initializing = false
|
||||
}
|
||||
|
||||
const outputs = initOutput($worldStore, id, {
|
||||
result: undefined,
|
||||
loading: false
|
||||
result,
|
||||
loading: initializing
|
||||
})
|
||||
|
||||
let result: string | undefined = undefined
|
||||
let style: 'Title' | 'Subtitle' | 'Body' | 'Caption' | 'Label' | undefined = undefined
|
||||
let copyButton: boolean
|
||||
let tooltip: string = ''
|
||||
|
||||
function getComponent() {
|
||||
switch (style) {
|
||||
switch (resolvedConfig.style) {
|
||||
case 'Title':
|
||||
return 'h1'
|
||||
case 'Subtitle':
|
||||
@@ -60,7 +69,7 @@
|
||||
}
|
||||
|
||||
function getClasses() {
|
||||
switch (style) {
|
||||
switch (resolvedConfig.style) {
|
||||
case 'Caption':
|
||||
return 'text-sm italic text-gray-500'
|
||||
case 'Label':
|
||||
@@ -72,13 +81,18 @@
|
||||
|
||||
let component = 'p'
|
||||
let classes = ''
|
||||
$: style && (component = getComponent())
|
||||
$: style && (classes = getClasses())
|
||||
$: resolvedConfig.style && (component = getComponent())
|
||||
$: resolvedConfig.style && (classes = getClasses())
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.style} bind:value={style} />
|
||||
<InputValue {id} input={configuration.copyButton} bind:value={copyButton} />
|
||||
<InputValue {id} input={configuration.tooltip} bind:value={tooltip} />
|
||||
{#each Object.keys(components['textcomponent'].initialData.configuration) as key (key)}
|
||||
<ResolveConfig
|
||||
{id}
|
||||
{key}
|
||||
bind:resolvedConfig={resolvedConfig[key]}
|
||||
configuration={configuration[key]}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
<RunnableWrapper {outputs} {render} {componentInput} {id} bind:initializing bind:result>
|
||||
<div class="h-full w-full overflow-hidden">
|
||||
@@ -113,10 +127,10 @@
|
||||
style={[$app.css?.['textcomponent']?.['text']?.style, customCss?.text?.style].join(';')}
|
||||
>
|
||||
{String(result)}
|
||||
{#if tooltip != ''}
|
||||
<Tooltip>{tooltip}</Tooltip>
|
||||
{#if resolvedConfig.tooltip != ''}
|
||||
<Tooltip>{resolvedConfig.tooltip}</Tooltip>
|
||||
{/if}
|
||||
{#if copyButton && result}
|
||||
{#if resolvedConfig.copyButton && result}
|
||||
<Popover notClickable>
|
||||
<Button
|
||||
variant="border"
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
}
|
||||
|
||||
async function getValue(input: AppInput) {
|
||||
if (!input) return
|
||||
if (input.type === 'template' && isCodeInjection(input.eval)) {
|
||||
try {
|
||||
const r = await eval_like(
|
||||
|
||||
@@ -92,7 +92,12 @@ export function getAllRecomputeIdsForComponent(app: App, id: string) {
|
||||
return recomputedBy
|
||||
}
|
||||
|
||||
export function createNewGridItem(grid: GridItem[], id: string, data: AppComponent): GridItem {
|
||||
export function createNewGridItem(
|
||||
grid: GridItem[],
|
||||
id: string,
|
||||
data: AppComponent,
|
||||
columns?: Record<number, any>
|
||||
): GridItem {
|
||||
const newComponent = {
|
||||
fixed: false,
|
||||
x: 0,
|
||||
@@ -108,12 +113,16 @@ export function createNewGridItem(grid: GridItem[], id: string, data: AppCompone
|
||||
}
|
||||
|
||||
gridColumns.forEach((column) => {
|
||||
const rec = getRecommendedDimensionsByComponent(newData.type, column)
|
||||
if (!columns) {
|
||||
const rec = getRecommendedDimensionsByComponent(newData.type, column)
|
||||
|
||||
newItem[column] = {
|
||||
...newComponent,
|
||||
w: rec.w,
|
||||
h: rec.h
|
||||
newItem[column] = {
|
||||
...newComponent,
|
||||
w: rec.w,
|
||||
h: rec.h
|
||||
}
|
||||
} else {
|
||||
newItem[column] = columns[column]
|
||||
}
|
||||
const position = gridHelp.findSpace(newItem, grid, column) as { x: number; y: number }
|
||||
newItem[column] = { ...newItem[column], ...position }
|
||||
@@ -190,6 +199,7 @@ export function insertNewGridItem(
|
||||
app: App,
|
||||
builddata: (id: string) => AppComponent,
|
||||
focusedGrid: FocusedGrid | undefined,
|
||||
columns?: Record<string, any>,
|
||||
keepId?: string
|
||||
): string {
|
||||
const id = keepId ?? getNextGridItemId(app)
|
||||
@@ -211,7 +221,7 @@ export function insertNewGridItem(
|
||||
: undefined
|
||||
let grid = focusedGrid ? app.subgrids[key!] : app.grid
|
||||
|
||||
const newItem = createNewGridItem(grid, id, data)
|
||||
const newItem = createNewGridItem(grid, id, data, columns)
|
||||
grid.push(newItem)
|
||||
|
||||
return id
|
||||
@@ -400,7 +410,17 @@ export function initConfig<
|
||||
}
|
||||
>
|
||||
>(
|
||||
r: T
|
||||
r: T,
|
||||
configuration?: Record<
|
||||
string,
|
||||
| StaticAppInput
|
||||
| {
|
||||
type: 'oneOf'
|
||||
selected: string
|
||||
configuration: Record<string, Record<string, StaticAppInput | EvalAppInput>>
|
||||
}
|
||||
| any
|
||||
>
|
||||
): {
|
||||
[Property in keyof T]: T[Property] extends StaticAppInput
|
||||
? T[Property]['value'] | undefined
|
||||
@@ -423,7 +443,10 @@ export function initConfig<
|
||||
Object.fromEntries(
|
||||
Object.entries(r).map(([key, value]) =>
|
||||
value.type == 'static'
|
||||
? [key, undefined]
|
||||
? [
|
||||
key,
|
||||
configuration?.[key]?.type == 'static' ? configuration?.[key]?.['value'] : undefined
|
||||
]
|
||||
: value.type == 'oneOf'
|
||||
? [
|
||||
key,
|
||||
@@ -433,7 +456,7 @@ export function initConfig<
|
||||
configuration: Object.fromEntries(
|
||||
Object.entries(value.configuration).map(([choice, config]) => [
|
||||
choice,
|
||||
initConfig(config)
|
||||
initConfig(config, configuration?.[key]?.configuration?.[choice])
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import type { AppEditorContext, AppViewerContext, GridItem } from '../../types'
|
||||
import { push } from '$lib/history'
|
||||
import { sendUserToast } from '$lib/utils'
|
||||
import { gridColumns } from '../../gridUtils'
|
||||
|
||||
const { app, selectedComponent, worldStore, focusedGrid, componentControl } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
@@ -172,7 +173,13 @@
|
||||
}
|
||||
|
||||
const gridItem = tempGridItem
|
||||
insertNewGridItem($app, (id) => ({ ...gridItem.data, id }), $focusedGrid, tempGridItem.id)
|
||||
insertNewGridItem(
|
||||
$app,
|
||||
(id) => ({ ...gridItem.data, id }),
|
||||
$focusedGrid,
|
||||
Object.fromEntries(gridColumns.map((column) => [column, gridItem[column]])),
|
||||
tempGridItem.id
|
||||
)
|
||||
|
||||
copiedGridItem = tempGridItem
|
||||
$selectedComponent = tempGridItem.id
|
||||
@@ -180,7 +187,12 @@
|
||||
tempGridItem = undefined
|
||||
} else if (copiedGridItem) {
|
||||
const gridItem = copiedGridItem
|
||||
$selectedComponent = insertNewGridItem($app, (id) => ({ ...gridItem.data, id }), $focusedGrid)
|
||||
$selectedComponent = insertNewGridItem(
|
||||
$app,
|
||||
(id) => ({ ...gridItem.data, id }),
|
||||
$focusedGrid,
|
||||
Object.fromEntries(gridColumns.map((column) => [column, gridItem[column]]))
|
||||
)
|
||||
}
|
||||
|
||||
$worldStore = $worldStore
|
||||
|
||||
@@ -319,7 +319,7 @@ export const components = {
|
||||
type: 'static',
|
||||
onlyStatic: true,
|
||||
selectOptions: selectOptions.textStyleOptions,
|
||||
value: 'Body'
|
||||
value: 'Body' as 'Title' | 'Subtitle' | 'Body' | 'Label' | 'Caption'
|
||||
},
|
||||
copyButton: {
|
||||
type: 'static',
|
||||
|
||||
@@ -122,7 +122,7 @@ type InputConfiguration<T extends InputType, V extends InputType> = {
|
||||
}
|
||||
|
||||
export type StaticOptions = {
|
||||
selectOptions: string[] | { value: string; label: string }[]
|
||||
selectOptions: readonly string[] | readonly { value: string; label: string }[]
|
||||
}
|
||||
|
||||
export type AppInput =
|
||||
|
||||
Reference in New Issue
Block a user