sunilkunchoor commented on issue #64336:
URL: https://github.com/apache/airflow/issues/64336#issuecomment-4156869356

   @Subham-KRLX  - Thanks so much for the PR. Your changes look solid!
   
   While you are touching the `ExtraLinks` stack, I had a quick thought for a 
UX enhancement. What if we allowed DAG authors to pass a structured Toaster 
object (Dictionary or Dataclass) directly from their `BaseOperatorLink`?
   
   Could we flow a custom toast object from the Python backend to the frontend 
`onClick` event. It would give users instant visual feedback when they click a 
link (especially useful for target="_self"), allowing authors to define custom 
titles, descriptions, and status colors.
   
   Here is the rough blueprint of how it could seamlessly fit into your current 
branch:
   
   1. **The Python Backend (`airflow/models/baseoperator.py`)**
   We can define a simple TypedDict or Dataclass for the toast, and add it to 
the base link:
   
   ```python
   from typing import TypedDict
   
   class LinkToastInfo(TypedDict, total=False):
       title: str
       description: str
       type: str  # 'info', 'success', 'warning', 'error'
   
   class BaseOperatorLink:
       name: str = "<Not specified>"
       target: str = "_blank"
       # New attribute for structured UI feedback
       toast: LinkToastInfo | None = None
   ```
   
   2. **The FastAPI Schema 
(`airflow/api_fastapi/core_api/datamodels/task_instances.py`)**
   Pass the nested dictionary through the Pydantic model:
   
   ```python
   class ExtraLinkToast(BaseModel):
       title: str
       description: str
       type: str = "info"
   
   class ExtraLinkItem(BaseModel):
       name: str
       url: str | None
       target: str = "_blank"
       toast: ExtraLinkToast | None = None  # Flow the object to the UI
   ```
   
   3. `The React Frontend (ExtraLinks.tsx)`
   Hook into Chakra v3's centralized toaster object to pop the notification. 
Because we passed a structured object, React can just destructure it
   
   ```ts
   import { toaster } from "src/components/ui"; 
   
   // ... inside your button mapping ...
   <Button
     as="a"
     href={link.url}
     target={link.target || "_blank"}
     onClick={() => {
       // Pop the custom toast if the DAG author provided the dictionary!
       if (link.toast) {
          toaster.create({
            title: link.toast.title || "Action Triggered",
            description: link.toast.description,
            type: link.toast.type || "info", 
          });
       }
     }}
   >
     {link.name}
   </Button>
   ```
   
   Let me know what you think — happy to help contribute this piece if you'd 
like to collaborate on it!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to