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 dedf4df66ad AIP-38: Add support for owner_links in DAG Header UI 
(#50627)
dedf4df66ad is described below

commit dedf4df66ad83d66df7640421fc2b475f43e3f11
Author: Yeonguk <[email protected]>
AuthorDate: Mon May 19 23:57:27 2025 +0900

    AIP-38: Add support for owner_links in DAG Header UI (#50627)
    
    * feat: Add owner_links field to DAGDetailsResponse model and update 
related schemas
    
    * feat: add owner_links to DAG Header owner section
    
    * remove owner_links in test code
    
    * add tests for DAG owner_links in DAG details endpoint
    
    * refactor: apply ruff formatting to test_dags.py
    
    * refactor: simplify DagOwners component
    
    * refactor: improve separator logic in DagOwners component
    
    * refactor: apply LimitedItemsList for cleaner item rendering logic
    
    * refactor: enhance Link component attributes
---
 .../src/airflow/ui/src/pages/Dag/Header.tsx        |  3 +-
 .../airflow/ui/src/pages/DagsList/DagOwners.tsx    | 55 ++++++++++++++++++++++
 2 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Header.tsx 
b/airflow-core/src/airflow/ui/src/pages/Dag/Header.tsx
index 94874dd8aea..c2e5fec62a0 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Header.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Header.tsx
@@ -28,6 +28,7 @@ import DisplayMarkdownButton from 
"src/components/DisplayMarkdownButton";
 import { HeaderCard } from "src/components/HeaderCard";
 import { TogglePause } from "src/components/TogglePause";
 
+import { DagOwners } from "../DagsList/DagOwners";
 import { DagTags } from "../DagsList/DagTags";
 import { Schedule } from "../DagsList/Schedule";
 
@@ -73,7 +74,7 @@ export const Header = ({
     },
     {
       label: "Owner",
-      value: dag?.owners.join(", "),
+      value: <DagOwners ownerLinks={dag?.owner_links ?? undefined} 
owners={dag?.owners} />,
     },
     {
       label: "Tags",
diff --git a/airflow-core/src/airflow/ui/src/pages/DagsList/DagOwners.tsx 
b/airflow-core/src/airflow/ui/src/pages/DagsList/DagOwners.tsx
new file mode 100644
index 00000000000..1ba38be2510
--- /dev/null
+++ b/airflow-core/src/airflow/ui/src/pages/DagsList/DagOwners.tsx
@@ -0,0 +1,55 @@
+/*!
+ * 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 { Link, Text } from "@chakra-ui/react";
+
+import { LimitedItemsList } from "src/components/LimitedItemsList";
+
+const DEFAULT_OWNERS: Array<string> = [];
+const MAX_OWNERS = 3;
+
+export const DagOwners = ({
+  ownerLinks,
+  owners = DEFAULT_OWNERS,
+}: {
+  readonly ownerLinks?: Record<string, string> | null;
+  readonly owners?: Array<string>;
+}) => {
+  const items = owners.map((owner) => {
+    const link = ownerLinks?.[owner];
+    const hasOwnerLink = link !== undefined;
+
+    return hasOwnerLink ? (
+      <Link
+        aria-label={`Owner link for ${owner}`}
+        href={link}
+        key={owner}
+        rel="noopener noreferrer"
+        target="_blank"
+      >
+        {owner}
+      </Link>
+    ) : (
+      <Text as="span" key={owner}>
+        {owner}
+      </Text>
+    );
+  });
+
+  return <LimitedItemsList interactive items={items} maxItems={MAX_OWNERS} />;
+};

Reply via email to