Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(frontend): Add missing loading state for non-runnable components … #3797

Merged
merged 8 commits into from
May 23, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@
$componentControl[id] = {
agGrid: { api: e.api, columnApi: e.columnApi },
setSelectedIndex: (index) => {
if(index === null) {
e.api.deselectAll();
if (index === null) {
e.api.deselectAll()
outputs?.selectedRow?.set({})
outputs?.selectedRowIndex.set(0)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
.ag-theme-alpine,
.ag-theme-alpine-dark,
.ag-theme-alpine-auto-dark {
--ag-alpine-active-color: rgb(255, 239, 254);
--ag-alpine-active-color: rgb(96, 165, 250);
--ag-selected-row-background-color: rgb(219, 234, 254, 0.5);
--ag-row-hover-color: rgb(191, 219, 254, 0.5);
--ag-column-hover-color: rgba(33, 150, 243, 0.1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<script lang="ts">
import { getContext } from 'svelte'
import type { AppInput } from '../../inputType'
import type { AppInput, InputConnectionEval } from '../../inputType'
import type { Output } from '../../rx'
import type { AppViewerContext } from '../../types'
import InputValue from './InputValue.svelte'
import InitializeComponent from './InitializeComponent.svelte'
import RefreshIndicator from './RefreshIndicator.svelte'

export let componentInput: AppInput
export let id: string
Expand All @@ -25,6 +26,46 @@
outputs?.result?.set(v, true)
}

let loading: boolean = false
let loadingStates: { [key: string]: boolean } = {}
let subscriptions: Array<() => void> = []

function updateGlobalLoading() {
loading = Object.values(loadingStates).some((state) => state === true)
}

function builtSubscriptions(connections: InputConnectionEval[]) {
// If we are rebuilding the subscriptions, we need to unsubscribe from the previous ones
if (subscriptions.length > 0) {
subscriptions.forEach((unsubscribe) => unsubscribe?.())
subscriptions = []
loadingStates = {}
loading = false
}

connections.forEach((connection) => {
const output = $worldStore.outputsById[connection.componentId]

if (output?.loading?.subscribe) {
const unsubscribe = output.loading.subscribe(
{
id: `loading-${connection.componentId}`,
next: (isConnectionLoading: boolean) => {
loadingStates[connection.componentId] = isConnectionLoading
updateGlobalLoading()
}
},
loadingStates[connection.componentId]
)
subscriptions.push(unsubscribe)
}
})
}

$: componentInput.type === 'evalv2' &&
componentInput.connections &&
builtSubscriptions(componentInput.connections)

$: result != undefined && outputs && setOutput(result)
</script>

Expand All @@ -39,6 +80,9 @@
{#if render || hasChildrens}
<div class={render ? 'h-full w-full' : 'invisible h-0 overflow-hidden'}>
<slot />
<div class="flex absolute top-1 right-1 z-50 app-component-refresh-btn">
<RefreshIndicator {loading} />
</div>
</div>
{:else}
<div class="w-full h-full" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts">
import { LoaderIcon } from 'lucide-svelte'
import Popover from '$lib/components/Popover.svelte'

export let loading: boolean
</script>

{#if loading}
<Popover>
<div class={'bg-blue-100 dark:bg-blue-400 transition-all p-1 rounded-component'}>
<LoaderIcon size={14} class="animate-spin text-blue-800 dark:text-white" />
</div>
<svelte:fragment slot="text">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slot for text in the Popover component should be named 'content' to match the expected API of the Popover component. This ensures that the text ('Refreshing...' or 'Refresh') is displayed correctly.

Suggested change
<svelte:fragment slot="text">
<svelte:fragment slot="content">

{#if loading}
Refreshing...
{:else}
Refresh
{/if}
</svelte:fragment>
</Popover>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import { Bug } from 'lucide-svelte'
import Popover from '$lib/components/Popover.svelte'
import ResolveStyle from '../helpers/ResolveStyle.svelte'
import { twMerge } from 'tailwind-merge'

export let id: string
export let configuration: RichConfigurations
Expand Down Expand Up @@ -227,6 +226,7 @@
inAppEditor={true}
--border-radius="0.250rem"
--clear-icon-color="#6b7280"
--border={$darkMode ? '1px solid #6b7280' : '1px solid #d1d5db'}
bind:filterText
on:filter={handleFilter}
on:clear={onClear}
Expand All @@ -238,7 +238,7 @@
? SELECT_INPUT_DEFAULT_STYLE.containerStylesDark
: SELECT_INPUT_DEFAULT_STYLE.containerStyles) + css?.input?.style}
{value}
class={twMerge($darkMode ? '!border-gray-500' : '!border-gray-300', css?.input?.class)}
class={css?.input?.class}
placeholder={resolvedConfig.placeholder}
disabled={resolvedConfig.disabled}
on:focus={() => {
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/lib/components/apps/rx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface Subscriber<T> {
}

export interface Observable<T> {
subscribe(x: Subscriber<T>, previousValue: T): void
subscribe(x: Subscriber<T>, previousValue: T): () => void
}
export interface Output<T> extends Observable<T> {
set(x: T, force?: boolean): void
Expand Down Expand Up @@ -154,6 +154,14 @@ export function settableOutput<T>(state: Writable<number>, previousValue: T): Ou
if (value !== undefined && !deepEqual(value, npreviousValue)) {
x.next(value)
}

// return a callback to unsubscribe
return () => {
const index = subscribers.findIndex((y) => y === x || (y.id && y.id === x.id))
if (index !== -1) {
subscribers.splice(index, 1)
}
}
}

let lastHash: any = undefined
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/lib/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export const SELECT_INPUT_DEFAULT_STYLE = {
inputStyles: 'border-radius: 0;',
containerStyles:
'--height: 34px; --padding: 0 0 0 8px; --font-size: 0.875rem; --border: 1px solid #d1d5db;',
containerStyles: '--height: 34px; --padding: 0 0 0 8px; --font-size: 0.875rem;',
containerStylesDark:
'--height: 34px; --padding: 0 0 0 8px; --font-size: 0.875rem; --border: 1px solid #374151; --background: #3b4252; --disabled-background: #2a2f3a; --list-background: #3b4252;--item-is-active-bg:#434c5e;--item-hover-bg:#4c566a;'
'--height: 34px; --padding: 0 0 0 8px; --font-size: 0.875rem; --background: #3b4252; --disabled-background: #2a2f3a; --list-background: #3b4252;--item-is-active-bg:#434c5e;--item-hover-bg:#4c566a;'
} as const
Loading