This is an automated email from the ASF dual-hosted git repository.

bbovenzi 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 3161a80f5b0 Fix Toaster in Plugin in Edge UI (#55641)
3161a80f5b0 is described below

commit 3161a80f5b0a1897dba915bae35be8a6301355f6
Author: Jens Scheffler <[email protected]>
AuthorDate: Mon Mar 2 17:31:55 2026 +0100

    Fix Toaster in Plugin in Edge UI (#55641)
    
    * Attempt to fix Toaster in Plugin
    
    * Attempt to fix via proposal
    
    * Revert testing of toaster open
    
    * Fix toaster using hints from Brent
---
 .../plugins/www/src/components/ui/createToaster.ts | 24 ------------
 .../edge3/plugins/www/src/components/ui/index.ts   |  2 +-
 .../plugins/www/src/components/ui/toaster.tsx      | 43 ++++++++++++++++++++++
 .../edge3/plugins/www/src/layouts/EdgeLayout.tsx   |  6 ++-
 4 files changed, 49 insertions(+), 26 deletions(-)

diff --git 
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/createToaster.ts
 
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/createToaster.ts
deleted file mode 100644
index 9fa1c393c77..00000000000
--- 
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/createToaster.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*!
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { createToaster } from "@chakra-ui/react";
-
-export const toaster = createToaster({
-  pauseOnPageIdle: true,
-  placement: "bottom-end",
-});
diff --git 
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/index.ts
 
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/index.ts
index 3ccf0201db1..8c8c86b328c 100644
--- 
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/index.ts
+++ 
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/index.ts
@@ -19,7 +19,7 @@
 
 export * from "./Alert";
 export * from "./CloseButton";
-export * from "./createToaster";
 export * from "./InputGroup";
+export * from "./toaster";
 export * from "./ScrollToAnchor";
 export * from "./Select";
diff --git 
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/toaster.tsx
 
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/toaster.tsx
new file mode 100644
index 00000000000..1ef0836f8a7
--- /dev/null
+++ 
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/components/ui/toaster.tsx
@@ -0,0 +1,43 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Toaster as ChakraToaster, Portal, Spinner, Stack, Toast, 
createToaster } from "@chakra-ui/react";
+import type { RefObject } from "react";
+
+export const toaster = createToaster({
+  pauseOnPageIdle: true,
+  placement: "bottom-end",
+});
+
+export const Toaster = ({ containerRef }: { containerRef: 
RefObject<HTMLDivElement | null> }) => (
+  <Portal container={containerRef}>
+    <ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
+      {(toast) => (
+        <Toast.Root width={{ md: "sm" }}>
+          {toast.type === "loading" ? <Spinner size="sm" color="blue.solid" /> 
: <Toast.Indicator />}
+          <Stack gap="1" flex="1" maxWidth="100%">
+            {toast.title && <Toast.Title>{toast.title}</Toast.Title>}
+            {toast.description && 
<Toast.Description>{toast.description}</Toast.Description>}
+          </Stack>
+          {toast.action && 
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>}
+          {toast.closable && <Toast.CloseTrigger />}
+        </Toast.Root>
+      )}
+    </ChakraToaster>
+  </Portal>
+);
diff --git 
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/EdgeLayout.tsx
 
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/EdgeLayout.tsx
index a53fed9d312..2f105d4417a 100644
--- 
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/EdgeLayout.tsx
+++ 
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/EdgeLayout.tsx
@@ -17,27 +17,31 @@
  * under the License.
  */
 import { Box } from "@chakra-ui/react";
+import { useRef } from "react";
 import { Navigate, Route, Routes } from "react-router-dom";
 
+import { Toaster } from "src/components/ui";
 import { JobsPage } from "src/pages/JobsPage";
 import { WorkerPage } from "src/pages/WorkerPage";
 
 import { NavTabs } from "./NavTabs";
 
 export const EdgeLayout = () => {
+  const containerRef = useRef<HTMLDivElement>(null);
   const tabs = [
     { label: "Edge Worker", value: "worker" },
     { label: "Edge Jobs", value: "jobs" },
   ];
 
   return (
-    <Box p={2} /* Compensate for parent padding from ExternalView */>
+    <Box ref={containerRef} p={2} /* Compensate for parent padding from 
ExternalView */>
       <NavTabs tabs={tabs} />
       <Routes>
         <Route index element={<Navigate to="worker" replace />} />
         <Route path="worker" element={<WorkerPage />} />
         <Route path="jobs" element={<JobsPage />} />
       </Routes>
+      <Toaster containerRef={containerRef} />
     </Box>
   );
 };

Reply via email to