This is an automated email from the ASF dual-hosted git repository.
pierrejeambrun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new e1d155c3d76 AIP-68 Fix multiple react app plugins (#54144)
e1d155c3d76 is described below
commit e1d155c3d762ab58604cb08312aebdb3fd1599a5
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Wed Aug 6 03:31:23 2025 +0200
AIP-68 Fix multiple react app plugins (#54144)
---
.../src/airflow/ui/src/pages/ReactPlugin.tsx | 36 ++++++++++++++--------
1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
index 8a193205634..1c1800044f7 100644
--- a/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/ReactPlugin.tsx
@@ -24,6 +24,13 @@ import type { ReactAppResponse } from
"openapi/requests/types.gen";
import { ErrorPage } from "./Error";
+type PluginComponentType = FC<{
+ dagId?: string;
+ mapIndex?: string;
+ runId?: string;
+ taskId?: string;
+}>;
+
export const ReactPlugin = ({ reactApp }: { readonly reactApp:
ReactAppResponse }) => {
const { dagId, mapIndex, runId, taskId } = useParams();
@@ -31,20 +38,23 @@ export const ReactPlugin = ({ reactApp }: { readonly
reactApp: ReactAppResponse
// We are assuming the plugin manager is trusted and the bundle_url is safe
import(/* @vite-ignore */ reactApp.bundle_url)
.then(() => {
- const component = (
- globalThis as unknown as {
- AirflowPlugin: FC<{
- dagId?: string;
- mapIndex?: string;
- runId?: string;
- taskId?: string;
- }>;
- }
- ).AirflowPlugin;
+ // Store components in globalThis[reactApp.name] to avoid conflicts
with the shared globalThis.AirflowPlugin
+ // global variable.
+ let pluginComponent = (globalThis as Record<string,
unknown>)[reactApp.name] as
+ | PluginComponentType
+ | undefined;
- return {
- default: component,
- };
+ if (pluginComponent === undefined) {
+ pluginComponent = (globalThis as Record<string,
unknown>).AirflowPlugin as PluginComponentType;
+
+ (globalThis as Record<string, unknown>)[reactApp.name] =
pluginComponent;
+ }
+
+ if (typeof pluginComponent !== "function") {
+ throw new TypeError(`Expected function, got ${typeof
pluginComponent} for plugin ${reactApp.name}`);
+ }
+
+ return { default: pluginComponent };
})
.catch((error: unknown) => {
console.error("Component Failed Loading:", error);