feat(frontend): Fix initial component dimensions + Select select + add spinner when buttons are clicked (#1044)
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Button, type ButtonType } from '$lib/components/common'
|
||||
import { faArrowRight, faRefresh } from '@fortawesome/free-solid-svg-icons'
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { Output } from '../../rx'
|
||||
import type { AppEditorContext } from '../../types'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
@@ -18,12 +20,31 @@
|
||||
|
||||
export const staticOutputs: string[] = ['loading', 'result']
|
||||
|
||||
const { runnableComponents } = getContext<AppEditorContext>('AppEditorContext')
|
||||
const { runnableComponents, worldStore } = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
let labelValue: string = 'Default label'
|
||||
let color: ButtonType.Color
|
||||
let size: ButtonType.Size
|
||||
let runnableComponent: RunnableComponent
|
||||
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
|
||||
$: outputs = $worldStore?.outputsById[id] as {
|
||||
result: Output<Array<any>>
|
||||
loading: Output<boolean>
|
||||
}
|
||||
|
||||
$: outputs?.loading.subscribe({
|
||||
next: (value) => {
|
||||
isLoading = value
|
||||
if (ownClick && !value) {
|
||||
ownClick = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$: loading = isLoading && ownClick
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.label} bind:value={labelValue} />
|
||||
@@ -40,6 +61,7 @@
|
||||
<AlignWrapper {horizontalAlignment} {verticalAlignment}>
|
||||
<Button
|
||||
on:click={() => {
|
||||
ownClick = true
|
||||
runnableComponent?.runComponent()
|
||||
|
||||
if (recomputeIds) {
|
||||
@@ -50,6 +72,10 @@
|
||||
}}
|
||||
{size}
|
||||
{color}
|
||||
endIcon={{
|
||||
icon: loading ? faRefresh : faArrowRight,
|
||||
classes: loading ? 'animate-spin w-4' : 'w-4'
|
||||
}}
|
||||
>
|
||||
{labelValue}
|
||||
</Button>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Button, type ButtonType } from '$lib/components/common'
|
||||
import { faArrowRight, faRefresh } from '@fortawesome/free-solid-svg-icons'
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { Output } from '../../rx'
|
||||
import type { AppEditorContext } from '../../types'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
@@ -17,12 +19,31 @@
|
||||
|
||||
export const staticOutputs: string[] = ['loading', 'result']
|
||||
|
||||
const { runnableComponents } = getContext<AppEditorContext>('AppEditorContext')
|
||||
const { runnableComponents, worldStore } = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
let labelValue: string = 'Default label'
|
||||
let color: ButtonType.Color
|
||||
let size: ButtonType.Size
|
||||
let runnableComponent: RunnableComponent
|
||||
|
||||
let isLoading: boolean = false
|
||||
let ownClick: boolean = false
|
||||
|
||||
$: outputs = $worldStore?.outputsById[id] as {
|
||||
result: Output<Array<any>>
|
||||
loading: Output<boolean>
|
||||
}
|
||||
|
||||
$: outputs?.loading.subscribe({
|
||||
next: (value) => {
|
||||
isLoading = value
|
||||
if (ownClick && !value) {
|
||||
ownClick = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$: loading = isLoading && ownClick
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.label} bind:value={labelValue} />
|
||||
@@ -50,6 +71,10 @@
|
||||
}}
|
||||
{size}
|
||||
{color}
|
||||
endIcon={{
|
||||
icon: loading ? faRefresh : faArrowRight,
|
||||
classes: loading ? 'animate-spin w-4' : 'w-4'
|
||||
}}
|
||||
>
|
||||
{labelValue}
|
||||
</Button>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import Select from 'svelte-select'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import type { Output } from '../../rx'
|
||||
@@ -13,7 +13,8 @@
|
||||
export let horizontalAlignment: 'left' | 'center' | 'right' | undefined = undefined
|
||||
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
|
||||
|
||||
const { worldStore } = getContext<AppEditorContext>('AppEditorContext')
|
||||
const { worldStore, connectingInput, selectedComponent } =
|
||||
getContext<AppEditorContext>('AppEditorContext')
|
||||
let label: string
|
||||
let items: string[]
|
||||
let itemKey: string
|
||||
@@ -25,6 +26,8 @@
|
||||
function onChange({ detail }: CustomEvent) {
|
||||
outputs?.result.set(detail?.[itemKey] || undefined)
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.label} bind:value={label} />
|
||||
@@ -32,5 +35,15 @@
|
||||
<InputValue {id} input={configuration.itemKey} bind:value={itemKey} />
|
||||
|
||||
<AlignWrapper {horizontalAlignment} {verticalAlignment}>
|
||||
<Select on:clear={onChange} on:change={onChange} {items} placeholder="Select an item" />
|
||||
<Select
|
||||
on:clear={onChange}
|
||||
on:change={onChange}
|
||||
{items}
|
||||
placeholder="Select an item"
|
||||
on:click={() => {
|
||||
if (!$connectingInput.opened) {
|
||||
$selectedComponent = id
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</AlignWrapper>
|
||||
|
||||
@@ -128,4 +128,7 @@
|
||||
/* Back shadow */
|
||||
background: rgb(147 197 253) !important;
|
||||
}
|
||||
:global(.svlt-grid-active) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -18,12 +18,18 @@
|
||||
function getMinDimensionsByComponent(componentType: AppComponent['type'], column: number): Size {
|
||||
// Dimensions key formula: <mobile width>:<mobile height>-<desktop width>:<desktop height>
|
||||
const dimensions: Record<`${number}:${number}-${number}:${number}`, AppComponent['type'][]> = {
|
||||
'1:2-3:2': ['buttoncomponent', 'textcomponent', 'checkboxcomponent'],
|
||||
'1:2-2:2': ['textinputcomponent', 'numberinputcomponent', 'selectcomponent'],
|
||||
'2:2-6:4': ['displaycomponent'],
|
||||
'2:3-6:4': ['formcomponent'],
|
||||
'2:4-6:4': ['barchartcomponent', 'piechartcomponent'],
|
||||
'3:4-12:4': ['tablecomponent']
|
||||
'1:2-2:2': [
|
||||
'buttoncomponent',
|
||||
'textcomponent',
|
||||
'checkboxcomponent',
|
||||
'textinputcomponent',
|
||||
'numberinputcomponent',
|
||||
'selectcomponent',
|
||||
'passwordinputcomponent',
|
||||
'dateinputcomponent'
|
||||
],
|
||||
'2:6-4:6': ['barchartcomponent', 'piechartcomponent', 'formcomponent', 'displaycomponent'],
|
||||
'3:6-6:8': ['tablecomponent']
|
||||
}
|
||||
// Finds the key that is associated with the component type and extracts the dimensions from it
|
||||
const [dimension] = Object.entries(dimensions).find(([_, value]) =>
|
||||
|
||||
Reference in New Issue
Block a user