This is an automated email from the ASF dual-hosted git repository.
vatsrahul1001 pushed a commit to branch v3-4-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-4-test by this push:
new 0b089451c91 [v3-4-test] UI: Drop the loading spinner for base React
plugins (#74762) (#74964)
0b089451c91 is described below
commit 0b089451c914d1c15d42bc26ec440759dfb7d133
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sun Oct 18 16:09:11 2026 +0530
[v3-4-test] UI: Drop the loading spinner for base React plugins (#74762)
(#74964)
A plugin with destination "base" renders above the content of every
page. While its bundle loads, ReactPlugin's Suspense fallback put a bare
spinner in the top left corner, so every full page load showed a stray
spinner until the bundle arrived. Base plugins now render nothing until
they are ready. Plugins on other destinations keep the spinner, since
they fill a page or tab that would otherwise be empty.
(cherry picked from commit 6cf83327d4687e121f6b2e332db300a7ce3491a3)
Co-authored-by: Julian LaNeve <[email protected]>
---
.../src/airflow/ui/src/pages/ReactPlugin.test.tsx | 17 +++++++++++++++++
airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx | 4 +++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.test.tsx
b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.test.tsx
index 6878743c55c..adbf65ee8ce 100644
--- a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.test.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.test.tsx
@@ -189,3 +189,20 @@ describe("loadPlugin", () => {
expect(component).not.toBe(componentA);
});
});
+
+const loading = (destination: ReactAppResponse["destination"]) =>
+ ({ bundle_url: "http://localhost/never-loaded.js", destination, name:
"Unloaded" }) as ReactAppResponse;
+
+describe("ReactPlugin loading fallback", () => {
+ it("shows a spinner while a page plugin's bundle loads", () => {
+ const { container } = render(<ReactPlugin reactApp={loading("dag")} />, {
wrapper: Wrapper });
+
+ expect(container.querySelector(".chakra-spinner")).toBeInTheDocument();
+ });
+
+ it("shows nothing while a base plugin's bundle loads", () => {
+ const { container } = render(<ReactPlugin reactApp={loading("base")} />, {
wrapper: Wrapper });
+
+ expect(container.querySelector(".chakra-spinner")).not.toBeInTheDocument();
+ });
+});
diff --git a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
index f454b6c806c..3d7b55a2d92 100644
--- a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
@@ -150,9 +150,11 @@ export const ReactPlugin = ({ reactApp }: { readonly
reactApp: ReactAppResponse
// Otherwise, lazy-load the bundle once. When it resolves, it must set a
function component
// under globalThis[reactApp.name], which we then use as the default export.
const LazyPlugin = lazy(() => loadPlugin(reactApp));
+ // A base plugin sits above every page, so a spinner there shows on every
full page load.
+ const fallback = reactApp.destination === "base" ? null : <Spinner />;
return (
- <Suspense fallback={<Spinner />}>
+ <Suspense fallback={fallback}>
<LazyPlugin {...pluginProps} />
</Suspense>
);