-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Show loading spinners immediately in ui (#1023)
I can't find any tickets on this even though I thought we had some. Fixes a few issues 1. Immediately open a panel and show a loading spinner before server rendering is complete The panel will be re-used and have its title updated if necessary when rendering completes. Works with multiple panels (opens 1 panel for loading and then re-uses for the 1st of multiple panels) 2. Shows a loader for all panels on page reload until rendering is complete. Previously, we rendered a blank panel until re-hydration was complete 3. If a widget throws a rendering error, the state is reset to loading when the "Reload" button is pressed. A loader is immediately shown until the reload is over instead of just showing the error message.
- Loading branch information
1 parent
701b004
commit 3748dac
Showing
8 changed files
with
179 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from deephaven import ui | ||
import time | ||
|
||
|
||
@ui.component | ||
def ui_boom_button(): | ||
value, set_value = ui.use_state(0) | ||
|
||
if value > 0: | ||
raise ValueError("BOOM! Value too big.") | ||
|
||
return ui.button("Go BOOM!", on_press=lambda _: set_value(value + 1)) | ||
|
||
|
||
@ui.component | ||
def ui_slow_multi_panel_component(): | ||
is_mounted, set_is_mounted = ui.use_state(None) | ||
if not is_mounted: | ||
time.sleep(1) | ||
set_is_mounted(ui_boom_button) # type: ignore Use a complex value that won't save between page loads | ||
return [ | ||
ui.panel(ui.button("Hello")), | ||
ui.panel(ui.text("World")), | ||
ui.panel(ui_boom_button()), | ||
] | ||
|
||
|
||
ui_slow_multi_panel = ui_slow_multi_panel_component() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { expect, test } from '@playwright/test'; | ||
import { openPanel, gotoPage, SELECTORS } from './utils'; | ||
|
||
test('slow multi-panel shows 1 loader immediately and multiple after loading', async ({ | ||
page, | ||
}) => { | ||
await gotoPage(page, ''); | ||
await openPanel( | ||
page, | ||
'ui_slow_multi_panel', | ||
SELECTORS.REACT_PANEL_VISIBLE, | ||
false | ||
); | ||
const locator = page.locator(SELECTORS.REACT_PANEL); | ||
// 1 loader should show up | ||
await expect(locator.locator('.loading-spinner')).toHaveCount(1); | ||
// Then disappear and show 3 panels | ||
await expect(locator.locator('.loading-spinner')).toHaveCount(0); | ||
await expect(locator).toHaveCount(3); | ||
await expect(locator.getByText('Hello')).toHaveCount(1); | ||
await expect(locator.getByText('World')).toHaveCount(1); | ||
await expect(locator.getByText('Go BOOM!')).toHaveCount(1); | ||
}); | ||
|
||
test('slow multi-panel shows loaders on element Reload', async ({ page }) => { | ||
await gotoPage(page, ''); | ||
await openPanel(page, 'ui_slow_multi_panel', SELECTORS.REACT_PANEL_VISIBLE); | ||
const locator = page.locator(SELECTORS.REACT_PANEL); | ||
await expect(locator).toHaveCount(3); | ||
await locator.getByText('Go BOOM!').click(); | ||
await expect(locator.getByText('ValueError', { exact: true })).toHaveCount(3); | ||
await expect(locator.getByText('BOOM!')).toHaveCount(3); | ||
await locator.locator(':visible').getByText('Reload').first().click(); | ||
// Loaders should show up | ||
await expect(locator.locator('.loading-spinner')).toHaveCount(3); | ||
// Then disappear and show components again | ||
await expect(locator.locator('.loading-spinner')).toHaveCount(0); | ||
await expect(locator.getByText('Hello')).toHaveCount(1); | ||
await expect(locator.getByText('World')).toHaveCount(1); | ||
await expect(locator.getByText('Go BOOM!')).toHaveCount(1); | ||
}); | ||
|
||
test('slow multi-panel shows loaders on page reload', async ({ page }) => { | ||
await gotoPage(page, ''); | ||
await openPanel(page, 'ui_slow_multi_panel', SELECTORS.REACT_PANEL_VISIBLE); | ||
await page.reload(); | ||
const locator = page.locator(SELECTORS.REACT_PANEL); | ||
// Loader should show up | ||
await expect(locator.locator('.loading-spinner')).toHaveCount(3); | ||
// Then disappear and show error again | ||
await expect(locator.locator('.loading-spinner')).toHaveCount(0); | ||
await expect(locator.getByText('Hello')).toHaveCount(1); | ||
await expect(locator.getByText('World')).toHaveCount(1); | ||
await expect(locator.getByText('Go BOOM!')).toHaveCount(1); | ||
}); |
Oops, something went wrong.