Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Box, Text, HStack, Link } from "@chakra-ui/react";
import { Box, Text, HStack } from "@chakra-ui/react";
import { FiDatabase } from "react-icons/fi";
import { PiRectangleDashed } from "react-icons/pi";
import { Link as RouterLink } from "react-router-dom";

import { RouterLink } from "src/components/ui";

import Time from "../Time";
import type { AssetSummary, NextRunEvent } from "./types";
Expand Down Expand Up @@ -47,9 +48,9 @@ export const AssetNode = ({
{"alias" in asset ? (
<Text fontSize="sm">{asset.alias.name}</Text>
) : (
<Link asChild color="fg.info" display="block" py={2}>
<RouterLink to={`/assets/${asset.asset.id}`}>{asset.asset.name}</RouterLink>
</Link>
<RouterLink display="block" py={2} to={`/assets/${asset.asset.id}`}>
{asset.asset.name}
</RouterLink>
)}
</HStack>
{event?.lastUpdate === undefined ? undefined : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Button, Flex, Link, Text } from "@chakra-ui/react";
import { Button, Flex, Text } from "@chakra-ui/react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink } from "react-router-dom";

import type { DagRunAssetReference, DagRunState } from "openapi/requests/types.gen";
import { Popover } from "src/components/ui";
import { Popover, RouterLink } from "src/components/ui";

import { StateBadge } from "../StateBadge";

Expand All @@ -40,11 +39,9 @@ export const TriggeredRuns = ({ dagRuns }: Props) => {
<Flex gap={1}>
<Text>{`${translate("triggered")} ${translate("dagRun_one")}`}: </Text>
<StateBadge state={dagRuns[0]?.state as DagRunState} />
<Link asChild color="fg.info">
<RouterLink to={`/dags/${dagRuns[0]?.dag_id}/runs/${dagRuns[0]?.run_id}`}>
{dagRuns[0]?.dag_id}
</RouterLink>
</Link>
<RouterLink to={`/dags/${dagRuns[0]?.dag_id}/runs/${dagRuns[0]?.run_id}`}>
{dagRuns[0]?.dag_id}
</RouterLink>
</Flex>
) : (
// eslint-disable-next-line jsx-a11y/no-autofocus
Expand All @@ -60,9 +57,7 @@ export const TriggeredRuns = ({ dagRuns }: Props) => {
{dagRuns.map((dagRun) => (
<Flex gap={1} key={dagRun.dag_id} my={2}>
<StateBadge state={dagRun.state as DagRunState} />
<Link asChild color="fg.info">
<RouterLink to={`/dags/${dagRun.dag_id}/runs/${dagRun.run_id}`}>{dagRun.dag_id}</RouterLink>
</Link>
<RouterLink to={`/dags/${dagRun.dag_id}/runs/${dagRun.run_id}`}>{dagRun.dag_id}</RouterLink>
</Flex>
))}
</Popover.Body>
Expand Down
30 changes: 30 additions & 0 deletions airflow-core/src/airflow/ui/src/components/ui/RouterLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*!
* 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 as ChakraLink, type LinkProps as ChakraLinkProps } from "@chakra-ui/react";
import { Link as ReactRouterLink, type To } from "react-router-dom";

type RouterLinkProps = {
readonly to: To;
} & Omit<ChakraLinkProps, "as" | "asChild" | "href">;

export const RouterLink = ({ children, to, ...rest }: RouterLinkProps) => (
<ChakraLink asChild color="fg.info" {...rest}>
<ReactRouterLink to={to}>{children}</ReactRouterLink>
</ChakraLink>
);
1 change: 1 addition & 0 deletions airflow-core/src/airflow/ui/src/components/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ export * from "./ResetButton";
export * from "./InputWithAddon";
export * from "./ButtonGroupToggle";
export * from "./LazyClipboard";
export * from "./RouterLink";
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Flex, Heading, Link, useDisclosure, VStack } from "@chakra-ui/react";
import { Flex, Heading, useDisclosure, VStack } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import { useTranslation } from "react-i18next";
import { useSearchParams, Link as RouterLink } from "react-router-dom";
import { useSearchParams } from "react-router-dom";

import { useAssetServiceGetAssets } from "openapi/queries";
import type { AssetResponse } from "openapi/requests/types.gen";
Expand All @@ -30,6 +30,7 @@ import { ExpandCollapseButtons } from "src/components/ExpandCollapseButtons";
import RenderedJsonField from "src/components/RenderedJsonField";
import { SearchBar } from "src/components/SearchBar";
import Time from "src/components/Time";
import { RouterLink } from "src/components/ui";
import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams";
import { useAdvancedSearch } from "src/hooks/useAdvancedSearch";
import { CreateAssetEvent } from "src/pages/Asset/CreateAssetEvent";
Expand All @@ -45,9 +46,9 @@ const createColumns = (
{
accessorKey: "name",
cell: ({ row: { original } }: AssetRow) => (
<Link asChild color="fg.info" fontWeight="bold">
<RouterLink to={`/assets/${original.id}`}>{original.name}</RouterLink>
</Link>
<RouterLink fontWeight="bold" to={`/assets/${original.id}`}>
{original.name}
</RouterLink>
),
header: () => translate("name"),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Button, Link } from "@chakra-ui/react";
import { Button } from "@chakra-ui/react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink } from "react-router-dom";

import type { DagScheduleAssetReference, TaskOutletAssetReference } from "openapi/requests/types.gen";
import { Popover } from "src/components/ui";
import { Popover, RouterLink } from "src/components/ui";

type Props = {
readonly dependencies: Array<DagScheduleAssetReference | TaskOutletAssetReference>;
Expand Down Expand Up @@ -57,9 +56,9 @@ export const DependencyPopover = ({ dependencies, type }: Props) => {
}

return (
<Link asChild color="fg.info" display="block" key={key} py={2}>
<RouterLink to={link}>{label}</RouterLink>
</Link>
<RouterLink display="block" key={key} py={2} to={link}>
{label}
</RouterLink>
);
})}
</Popover.Body>
Expand Down
24 changes: 11 additions & 13 deletions airflow-core/src/airflow/ui/src/pages/Dag/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Link } from "@chakra-ui/react";
import { useTranslation } from "react-i18next";
import { FiBookOpen } from "react-icons/fi";
import { useParams, Link as RouterLink } from "react-router-dom";
import { useParams } from "react-router-dom";

import type { DAGDetailsResponse, DagRunState } from "openapi/requests/types.gen";
import { DagIcon } from "src/assets/DagIcon";
Expand All @@ -32,6 +31,7 @@ import { DagVersion } from "src/components/DagVersion";
import DisplayMarkdownButton from "src/components/DisplayMarkdownButton";
import { HeaderCard } from "src/components/HeaderCard";
import { TogglePause } from "src/components/TogglePause";
import { RouterLink } from "src/components/ui";

import { DagOwners } from "../DagsList/DagOwners";
import { DagTags } from "../DagsList/DagTags";
Expand Down Expand Up @@ -93,17 +93,15 @@ export const Header = ({
label: translate("dagDetails.latestRun"),
value:
Boolean(latestRunInfo) && latestRunInfo !== undefined ? (
<Link asChild color="fg.info">
<RouterLink to={`/dags/${latestRunInfo.dag_id}/runs/${latestRunInfo.run_id}`}>
<DagRunInfo
endDate={latestRunInfo.end_date}
logicalDate={latestRunInfo.logical_date}
runAfter={latestRunInfo.run_after}
startDate={latestRunInfo.start_date}
state={latestRunInfo.state}
/>
</RouterLink>
</Link>
<RouterLink to={`/dags/${latestRunInfo.dag_id}/runs/${latestRunInfo.run_id}`}>
<DagRunInfo
endDate={latestRunInfo.end_date}
logicalDate={latestRunInfo.logical_date}
runAfter={latestRunInfo.run_after}
startDate={latestRunInfo.start_date}
state={latestRunInfo.state}
/>
</RouterLink>
) : undefined,
},
...nextRunStat,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Badge, HStack, Link, Text, VStack } from "@chakra-ui/react";
import { Badge, HStack, Text, VStack } from "@chakra-ui/react";
import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import relativeTime from "dayjs/plugin/relativeTime";
import { useTranslation } from "react-i18next";
import { FiAlertTriangle, FiClock } from "react-icons/fi";
import { Link as RouterLink } from "react-router-dom";

import type { DeadlineAlertResponse, DeadlineResponse } from "openapi/requests/types.gen";
import Time from "src/components/Time";
import { RouterLink } from "src/components/ui";

dayjs.extend(duration);
dayjs.extend(relativeTime);
Expand Down Expand Up @@ -53,11 +53,13 @@ export const DeadlineRow = ({ alert, deadline }: DeadlineRowProps) => {
{deadline.missed ? <FiAlertTriangle /> : <FiClock />}
{translate(deadline.missed ? "deadlineStatus.missed" : "deadlineStatus.upcoming")}
</Badge>
<Link asChild color="fg.info" fontSize="sm" fontWeight="bold">
<RouterLink to={`/dags/${deadline.dag_id}/runs/${deadline.dag_run_id}`}>
{deadline.dag_run_id}
</RouterLink>
</Link>
<RouterLink
fontSize="sm"
fontWeight="bold"
to={`/dags/${deadline.dag_id}/runs/${deadline.dag_run_id}`}
>
{deadline.dag_run_id}
</RouterLink>
</HStack>
{reference !== undefined && interval !== undefined ? (
<Text color="fg.muted" fontSize="xs">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Box, Flex, Link, Button } from "@chakra-ui/react";
import { Box, Flex, Button } from "@chakra-ui/react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink } from "react-router-dom";

import type { TaskInstanceResponse } from "openapi/requests/types.gen";
import { ClearTaskInstanceButton } from "src/components/Clear";
import { StateBadge } from "src/components/StateBadge";
import Time from "src/components/Time";
import { RouterLink } from "src/components/ui";
import { TaskLogContent } from "src/pages/TaskInstance/Logs/TaskLogContent";
import { useLogs } from "src/queries/useLogs";
import { getTaskInstanceLink } from "src/utils/links";
Expand Down Expand Up @@ -73,11 +73,9 @@ export const TaskLogPreview = ({
: translate("overview.failedLogs.showLogs")}
</Button>
<ClearTaskInstanceButton taskInstance={taskInstance} />
<Link asChild color="fg.info" fontSize="sm">
<RouterLink to={getTaskInstanceLink(taskInstance)}>
{translate("overview.failedLogs.viewFullLogs")}
</RouterLink>
</Link>
<RouterLink fontSize="sm" to={getTaskInstanceLink(taskInstance)}>
{translate("overview.failedLogs.viewFullLogs")}
</RouterLink>
</Flex>
</Flex>
{isExpanded ? (
Expand Down
12 changes: 5 additions & 7 deletions airflow-core/src/airflow/ui/src/pages/Dag/Tasks/Tasks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Box, Link } from "@chakra-ui/react";
import { Box } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import type { TFunction } from "i18next";
import { useTranslation } from "react-i18next";
import { useParams, useSearchParams } from "react-router-dom";
import { Link as RouterLink } from "react-router-dom";

import { useTaskServiceGetTasks } from "openapi/queries";
import type { TaskResponse } from "openapi/requests/types.gen";
import { DataTable } from "src/components/DataTable";
import { ErrorAlert } from "src/components/ErrorAlert";
import { TruncatedText } from "src/components/TruncatedText";
import { RouterLink } from "src/components/ui";
import { SearchParamsKeys } from "src/constants/searchParams.ts";
import { TaskFilters } from "src/pages/Dag/Tasks/TaskFilters/TaskFilters.tsx";

Expand All @@ -43,11 +43,9 @@ const createColumns = ({
{
accessorKey: "task_display_name",
cell: ({ row: { original } }: TaskRow) => (
<Link asChild color="fg.info" fontWeight="bold">
<RouterLink to={`/dags/${dagId}/tasks/${original.task_id}`}>
<TruncatedText text={original.task_display_name ?? original.task_id ?? ""} />
</RouterLink>
</Link>
<RouterLink fontWeight="bold" to={`/dags/${dagId}/tasks/${original.task_id}`}>
<TruncatedText text={original.task_display_name ?? original.task_id ?? ""} />
</RouterLink>
),
enableSorting: false,
header: translate("common:taskId"),
Expand Down
29 changes: 12 additions & 17 deletions airflow-core/src/airflow/ui/src/pages/DagRuns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Flex, HStack, Link, Text } from "@chakra-ui/react";
import { Flex, HStack, Text } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import type { TFunction } from "i18next";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useParams, useSearchParams } from "react-router-dom";
import { useParams, useSearchParams } from "react-router-dom";

import { useDagRunServiceGetDagRuns } from "openapi/queries";
import type { DAGRunResponse } from "openapi/requests/types.gen";
Expand All @@ -36,6 +36,7 @@ import { RunTypeIcon } from "src/components/RunTypeIcon";
import { StateBadge } from "src/components/StateBadge";
import Time from "src/components/Time";
import { TruncatedText } from "src/components/TruncatedText";
import { RouterLink } from "src/components/ui";
import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams";
import { useAdvancedSearchArg } from "src/hooks/useAdvancedSearch";
import { DagRunsFilters } from "src/pages/DagRunsFilters";
Expand Down Expand Up @@ -73,11 +74,9 @@ const runColumns = (translate: TFunction, dagId?: string): Array<ColumnDef<DAGRu
{
accessorKey: "dag_display_name",
cell: ({ row: { original } }: DagRunRow) => (
<Link asChild color="fg.info">
<RouterLink to={`/dags/${original.dag_id}`}>
<TruncatedText text={original.dag_display_name} />
</RouterLink>
</Link>
<RouterLink to={`/dags/${original.dag_id}`}>
<TruncatedText text={original.dag_display_name} />
</RouterLink>
),
enableSorting: false,
header: translate("dagId"),
Expand All @@ -86,22 +85,18 @@ const runColumns = (translate: TFunction, dagId?: string): Array<ColumnDef<DAGRu
{
accessorKey: "dag_run_id",
cell: ({ row: { original } }: DagRunRow) => (
<Link asChild color="fg.info" fontWeight="bold">
<RouterLink to={`/dags/${original.dag_id}/runs/${original.dag_run_id}`}>
<TruncatedText text={original.dag_run_id} />
</RouterLink>
</Link>
<RouterLink fontWeight="bold" to={`/dags/${original.dag_id}/runs/${original.dag_run_id}`}>
<TruncatedText text={original.dag_run_id} />
</RouterLink>
),
header: translate("dagRunId"),
},
{
accessorKey: "run_after",
cell: ({ row: { original } }: DagRunRow) => (
<Link asChild color="fg.info" fontWeight="bold">
<RouterLink to={`/dags/${original.dag_id}/runs/${original.dag_run_id}`}>
<Time datetime={original.run_after} />
</RouterLink>
</Link>
<RouterLink fontWeight="bold" to={`/dags/${original.dag_id}/runs/${original.dag_run_id}`}>
<Time datetime={original.run_after} />
</RouterLink>
),
header: translate("dagRun.runAfter"),
},
Expand Down
Loading
Loading