mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 08:01:35 +00:00
feat: eager app mode
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import { getContext, onDestroy } from 'svelte'
|
||||
import { initConfig, initOutput } from '../../editor/appUtils'
|
||||
import type {
|
||||
AppViewerContext,
|
||||
ComponentCustomCSS,
|
||||
VerticalAlignment,
|
||||
RichConfigurations
|
||||
RichConfigurations,
|
||||
ListContext,
|
||||
ListInputs
|
||||
} from '../../types'
|
||||
import { initCss } from '../../utils'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
@@ -27,24 +29,36 @@
|
||||
const { app, worldStore, componentControl, selectedComponent } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const iterContext = getContext<ListContext>('ListWrapperContext')
|
||||
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
components['datetimeinputcomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
let value: string | undefined = undefined
|
||||
|
||||
$componentControl[id] = {
|
||||
setValue(nvalue: string) {
|
||||
value = nvalue
|
||||
}
|
||||
}
|
||||
|
||||
let outputs = initOutput($worldStore, id, {
|
||||
result: undefined as string | undefined,
|
||||
validity: true as boolean | undefined
|
||||
})
|
||||
|
||||
let initValue = outputs?.result.peak()
|
||||
let value: string | undefined =
|
||||
!iterContext && initValue != undefined ? initValue : resolvedConfig.defaultValue
|
||||
|
||||
$componentControl[id] = {
|
||||
setValue(nvalue: string) {
|
||||
value = nvalue
|
||||
outputs?.result.set(value)
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
listInputs?.remove(id)
|
||||
})
|
||||
|
||||
let initialHandleDefault = true
|
||||
|
||||
$: handleDefault(resolvedConfig.defaultValue)
|
||||
|
||||
function formatDate(dateString: string, formatString: string = 'dd.MM.yyyy HH:mm') {
|
||||
@@ -62,7 +76,8 @@
|
||||
|
||||
$: {
|
||||
if (value) {
|
||||
outputs?.result.set(formatDate(value, resolvedConfig.outputFormat))
|
||||
const r = formatDate(value, resolvedConfig.outputFormat)
|
||||
outputs?.result.set(r)
|
||||
const valueDate = new Date(value)
|
||||
|
||||
if (resolvedConfig.minDateTime) {
|
||||
@@ -95,12 +110,24 @@
|
||||
outputs?.validity.set(false)
|
||||
}
|
||||
}
|
||||
if (iterContext && listInputs) {
|
||||
listInputs.set(id, value)
|
||||
}
|
||||
} else {
|
||||
outputs?.result.set(undefined)
|
||||
if (iterContext && listInputs) {
|
||||
listInputs.set(id, undefined)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleDefault(defaultValue: string | undefined) {
|
||||
if (initialHandleDefault) {
|
||||
initialHandleDefault = false
|
||||
if (value != undefined) {
|
||||
return
|
||||
}
|
||||
}
|
||||
value = defaultValue
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
// initialized?.length ==
|
||||
// allItems(app.grid, app.subgrids).length + (app.hiddenInlineScripts?.length ?? 0)
|
||||
// )
|
||||
if (app.lazyInitRequire == undefined) {
|
||||
if (app.eagerRendering || app.lazyInitRequire == undefined) {
|
||||
return (
|
||||
initialized?.length ==
|
||||
allItems(app.grid, app.subgrids).length + (app.hiddenInlineScripts?.length ?? 0)
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if everVisible}
|
||||
{#if everVisible || $app.eagerRendering}
|
||||
<div
|
||||
class="translate-x-0 translate-y-0 w-full subgrid {visible
|
||||
? 'visible'
|
||||
|
||||
@@ -3,12 +3,19 @@
|
||||
import type { AppViewerContext } from '../../types'
|
||||
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
import Toggle from '$lib/components/Toggle.svelte'
|
||||
import JsonEditor from '$lib/components/JsonEditor.svelte'
|
||||
import Section from '$lib/components/Section.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
|
||||
const { app } = getContext<AppViewerContext>('AppViewerContext')
|
||||
let code = JSON.stringify($app.lazyInitRequire)
|
||||
|
||||
let selectedRendering = $app.eagerRendering
|
||||
? 'eager'
|
||||
: $app.lazyInitRequire
|
||||
? 'lazy'
|
||||
: 'semi-lazy'
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-8" style="all:none;">
|
||||
@@ -19,32 +26,51 @@
|
||||
When lazy mode is enabled, components are not rendered until they are needed. This can significantly
|
||||
improve the performance of your app, especially on mobile devices.
|
||||
<br />
|
||||
You can enable lazy mode below, but you will need to declare the list of components whose initialization
|
||||
is expected to see initialized before the initial refresh of the app happens.
|
||||
Semi-Lazy mode is enabled by default, where components are initialized but are in a hidden state.
|
||||
Lazy mode is when components are not initialized at all.
|
||||
</Alert>
|
||||
|
||||
<Toggle
|
||||
label="Lazy mode"
|
||||
checked={Boolean($app.lazyInitRequire != undefined)}
|
||||
on:change={(e) => {
|
||||
$app.lazyInitRequire = e.detail ? [] : undefined
|
||||
code = JSON.stringify($app.lazyInitRequire)
|
||||
<ToggleButtonGroup
|
||||
label="Rendering"
|
||||
bind:selected={selectedRendering}
|
||||
on:selected={(e) => {
|
||||
if (e.detail == 'eager') {
|
||||
$app.eagerRendering = true
|
||||
$app.lazyInitRequire = undefined
|
||||
} else if (e.detail == 'semi-lazy') {
|
||||
$app.eagerRendering = undefined
|
||||
$app.lazyInitRequire = undefined
|
||||
} else {
|
||||
$app.eagerRendering = undefined
|
||||
$app.lazyInitRequire = []
|
||||
code = JSON.stringify($app.lazyInitRequire)
|
||||
}
|
||||
}}
|
||||
options={{
|
||||
right: 'Lazy mode'
|
||||
}}
|
||||
/>
|
||||
|
||||
<Section label="Component ids to wait the initialization of before the initial refresh">
|
||||
{#if $app.lazyInitRequire != undefined}
|
||||
let:item
|
||||
>
|
||||
<ToggleButton value="eager" label="Eager" {item} />
|
||||
<ToggleButton value="semi-lazy" label="Semi-Lazy" {item} />
|
||||
<ToggleButton value="lazy" label="Lazy" {item} />
|
||||
</ToggleButtonGroup>
|
||||
{#if selectedRendering == 'eager'}
|
||||
<Section label="Eager mode">
|
||||
<span class="text-tertiary"
|
||||
>In eager mode, all components will be fully initialized, even when they are not visible.</span
|
||||
>
|
||||
</Section>
|
||||
{:else if selectedRendering == 'semi-lazy'}
|
||||
<Section label="Semi-Lazy mode">
|
||||
<span class="text-tertiary"
|
||||
>In semi-lazy mode, components will be semi-initialized when hidden. That is the default
|
||||
mode.</span
|
||||
>
|
||||
</Section>
|
||||
{:else if selectedRendering == 'lazy'}
|
||||
<Section label="Component ids to wait the initialization of before the initial refresh">
|
||||
<JsonEditor bind:value={$app.lazyInitRequire} {code} />
|
||||
<span class="text-tertiary text-xs">
|
||||
{'e.g: ["a", "b"]'}, no need to put background runnables ids
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-tertiary"
|
||||
>Without lazy mode, all components' initialization will be waited on the initial refresh.</span
|
||||
>
|
||||
{/if}
|
||||
</Section>
|
||||
</Section>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -165,6 +165,7 @@ export type App = {
|
||||
subgrids?: Record<string, GridItem[]>
|
||||
theme: AppTheme | undefined
|
||||
lazyInitRequire?: string[] | undefined
|
||||
eagerRendering?: boolean | undefined
|
||||
hideLegacyTopBar?: boolean | undefined
|
||||
mobileViewOnSmallerScreens?: boolean | undefined
|
||||
version?: number
|
||||
|
||||
Reference in New Issue
Block a user