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 9ef89acf85d AIP-38 List providers (#45535)
9ef89acf85d is described below
commit 9ef89acf85dffe69266b716fa0fa1cfa6246b1f3
Author: Linh <[email protected]>
AuthorDate: Fri Jan 31 16:34:13 2025 +0700
AIP-38 List providers (#45535)
* rebasing
* fix regex
* remove pnpm from package.json
---
airflow/ui/src/layouts/Nav/AdminButton.tsx | 4 ++
airflow/ui/src/pages/Providers.tsx | 83 ++++++++++++++++++++++++++++++
airflow/ui/src/router.tsx | 5 ++
3 files changed, 92 insertions(+)
diff --git a/airflow/ui/src/layouts/Nav/AdminButton.tsx
b/airflow/ui/src/layouts/Nav/AdminButton.tsx
index 7889f4ede56..53ad5c9d4d7 100644
--- a/airflow/ui/src/layouts/Nav/AdminButton.tsx
+++ b/airflow/ui/src/layouts/Nav/AdminButton.tsx
@@ -32,6 +32,10 @@ const links = [
href: "/pools",
title: "Pools",
},
+ {
+ href: "/providers",
+ title: "Providers",
+ },
];
export const AdminButton = () => (
diff --git a/airflow/ui/src/pages/Providers.tsx
b/airflow/ui/src/pages/Providers.tsx
new file mode 100644
index 00000000000..8c05f434d5d
--- /dev/null
+++ b/airflow/ui/src/pages/Providers.tsx
@@ -0,0 +1,83 @@
+/*!
+ * 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 { Box, Heading, Link } from "@chakra-ui/react";
+import type { ColumnDef } from "@tanstack/react-table";
+
+import { useProviderServiceGetProviders } from "openapi/queries";
+import type { ProviderResponse } from "openapi/requests/types.gen";
+import { DataTable } from "src/components/DataTable";
+import { ErrorAlert } from "src/components/ErrorAlert";
+
+const columns: Array<ColumnDef<ProviderResponse>> = [
+ {
+ accessorKey: "package_name",
+ cell: ({ row: { original } }) => (
+ <Link
+ aria-label={original.package_name}
+ color="fg.info"
+
href={`https://airflow.apache.org/docs/${original.package_name}/${original.version}/`}
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ {original.package_name}
+ </Link>
+ ),
+ header: "Package Name",
+ },
+ {
+ accessorKey: "version",
+ cell: ({ row: { original } }) => original.version,
+ header: () => "Version",
+ },
+ {
+ accessorKey: "description",
+ cell: ({ row: { original } }) => {
+ const urlRegex =
/http(s)?:\/\/[\w.-]+(\.?:[\w.-]+)*([#/?][\w!#$%&'()*+,./:;=?@[\]~-]*)?/gu;
+ const urls = original.description.match(urlRegex);
+ const cleanText = original.description.replaceAll(/\n(?:and)?/gu, "
").split(" ");
+
+ return cleanText.map((part) =>
+ urls?.includes(part) ? (
+ <Link color="fg.info" href={part} key={part} rel="noopener
noreferrer" target="_blank">
+ {part}
+ </Link>
+ ) : (
+ `${part} `
+ ),
+ );
+ },
+ header: "Description",
+ },
+];
+
+export const Providers = () => {
+ const { data, error } = useProviderServiceGetProviders();
+
+ return (
+ <Box p={2}>
+ <Heading>Providers</Heading>
+ <DataTable
+ columns={columns}
+ data={data?.providers ?? []}
+ errorMessage={<ErrorAlert error={error} />}
+ total={data?.total_entries}
+ />
+ </Box>
+ );
+};
diff --git a/airflow/ui/src/router.tsx b/airflow/ui/src/router.tsx
index 5e5f1b3a576..24a5c7240cb 100644
--- a/airflow/ui/src/router.tsx
+++ b/airflow/ui/src/router.tsx
@@ -31,6 +31,7 @@ import { DagsList } from "src/pages/DagsList";
import { Dashboard } from "src/pages/Dashboard";
import { ErrorPage } from "src/pages/Error";
import { Events } from "src/pages/Events";
+import { Providers } from "src/pages/Providers";
import { Run } from "src/pages/Run";
import { Details as DagRunDetails } from "src/pages/Run/Details";
import { TaskInstances } from "src/pages/Run/TaskInstances";
@@ -70,6 +71,10 @@ export const routerConfig = [
element: <Pools />,
path: "pools",
},
+ {
+ element: <Providers />,
+ path: "providers",
+ },
{
children: [
{ element: <Overview />, index: true },