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
3 changes: 3 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Asset/AssetLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { BreadcrumbStats } from "src/components/BreadcrumbStats";
import { ProgressBar } from "src/components/ui";
import { GroupsProvider } from "src/context/groups";
import { NavTabs } from "src/layouts/Details/NavTabs";
import { useDocumentTitle } from "src/utils";

import { AssetGraph } from "./AssetGraph";
import { AssetPanelButtons } from "./AssetPanelButtons";
Expand All @@ -49,6 +50,8 @@ export const AssetLayout = () => {
},
);

useDocumentTitle(asset?.name);

const links = [
{
label: asset?.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ 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";
import { useDocumentTitle } from "src/utils";

import { DependencyPopover } from "./DependencyPopover";

Expand Down Expand Up @@ -117,6 +118,9 @@ const { NAME_PATTERN, OFFSET }: SearchParamsKeysType = SearchParamsKeys;

export const AssetsList = () => {
const { t: translate } = useTranslation(["assets", "common"]);

useDocumentTitle(translate("common:nav.assets"));

const [searchParams, setSearchParams] = useSearchParams();

const namePattern = searchParams.get(NAME_PATTERN) ?? "";
Expand Down
4 changes: 4 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Configs/Configs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { useConfigServiceGetConfig } from "openapi/queries";
import type { ConfigOption } from "openapi/requests/types.gen";
import { DataTable } from "src/components/DataTable";
import { ErrorAlert } from "src/components/ErrorAlert";
import { useDocumentTitle } from "src/utils";

type ConfigColums = {
section: string;
Expand All @@ -50,6 +51,9 @@ const createColumns = (translate: TFunction): Array<ColumnDef<ConfigColums>> =>

export const Configs = () => {
const { t: translate } = useTranslation(["admin", "common"]);

useDocumentTitle(translate("common:admin.Config"));

const { data, error } = useConfigServiceGetConfig();

const columns = createColumns(translate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searc
import { useAdvancedSearch } from "src/hooks/useAdvancedSearch";
import { useConfig } from "src/queries/useConfig.tsx";
import { useConnectionTypeMeta } from "src/queries/useConnectionTypeMeta";
import { useDocumentTitle } from "src/utils";

import AddConnectionButton from "./AddConnectionButton";
import DeleteConnectionButton from "./DeleteConnectionButton";
Expand Down Expand Up @@ -132,6 +133,9 @@ const getColumns = ({

export const Connections = () => {
const { t: translate } = useTranslation(["admin", "common"]);

useDocumentTitle(translate("common:admin.Connections"));

const { setTableURLState, tableURLState } = useTableURLState();
const [searchParams, setSearchParams] = useSearchParams();
const { NAME_PATTERN, OFFSET }: SearchParamsKeysType = SearchParamsKeys;
Expand Down
6 changes: 5 additions & 1 deletion airflow-core/src/airflow/ui/src/pages/DagRuns/DagRuns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { RouterLink } from "src/components/ui";
import { ActionBar } from "src/components/ui/ActionBar";
import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams";
import { useAdvancedSearchArg } from "src/hooks/useAdvancedSearch";
import { renderDuration, useAutoRefresh, isStatePending } from "src/utils";
import { renderDuration, useAutoRefresh, isStatePending, useDocumentTitle } from "src/utils";

import BulkClearDagRunsButton from "./BulkClearDagRunsButton";
import BulkDeleteDagRunsButton from "./BulkDeleteDagRunsButton";
Expand Down Expand Up @@ -221,6 +221,10 @@ const runColumns = ({ dagId, translate }: ColumnProps): Array<ColumnDef<DAGRunRe
export const DagRuns = () => {
const { t: translate } = useTranslation();
const { dagId } = useParams();

// Only the standalone list page owns the tab title; the Dag-scoped tab inherits the Dag page's title.
useDocumentTitle(dagId === undefined ? translate("common:dagRun_other") : undefined);

const [searchParams] = useSearchParams();

const { setTableURLState, tableURLState } = useTableURLState({
Expand Down
4 changes: 4 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/DagsList/DagsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { DagsLayout } from "src/layouts/DagsLayout";
import { useConfig } from "src/queries/useConfig";
import { useDagRunStateCounts } from "src/queries/useDagRunStateCounts";
import { useDags } from "src/queries/useDags";
import { useDocumentTitle } from "src/utils";

import { DagImportErrors } from "../Dashboard/Stats/DagImportErrors";
import { DagCard } from "./DagCard";
Expand Down Expand Up @@ -218,6 +219,9 @@ const createCardDef = (runStateContext: RunStateCountsContext): CardDef<DAGWithL

export const DagsList = () => {
const { t: translate } = useTranslation();

useDocumentTitle(translate("common:nav.dags"));

const [searchParams, setSearchParams] = useSearchParams();
const [display, setDisplay] = useLocalStorage<"card" | "table">(DAGS_LIST_DISPLAY_KEY, "card");
const dagRunsLimit = display === "card" ? 14 : 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import TimeRangeSelector from "src/components/TimeRangeSelector";
import { IconButton } from "src/components/ui";
import { COLLAPSED_UI_ALERTS_KEY } from "src/constants/localStorage";
import { useConfig } from "src/queries/useConfig";
import { useDocumentTitle } from "src/utils";

import { ReactPlugin } from "../ReactPlugin";
import { AlertContent } from "./AlertContent";
Expand All @@ -44,6 +45,9 @@ const defaultHour = "24";
export const Dashboard = () => {
const alerts = useConfig("dashboard_alert") as Array<UIAlert>;
const { t: translate } = useTranslation("dashboard");

useDocumentTitle(translate("common:nav.home"));

const instanceName = useConfig("instance_name");

const now = dayjs();
Expand Down
5 changes: 4 additions & 1 deletion airflow-core/src/airflow/ui/src/pages/Deadlines/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { FilterBar } from "src/components/FilterBar";
import Time from "src/components/Time";
import { TruncatedText } from "src/components/TruncatedText";
import { SearchParamsKeys } from "src/constants/searchParams";
import { useFiltersHandler, type FilterableSearchParamsKeys } from "src/utils";
import { useDocumentTitle, useFiltersHandler, type FilterableSearchParamsKeys } from "src/utils";

type DeadlineRow = { row: { original: DeadlineResponse } };

Expand Down Expand Up @@ -100,6 +100,9 @@ const deadlinesFilterKeys: Array<FilterableSearchParamsKeys> = [

export const Deadlines = () => {
const { t: translate } = useTranslation(["browse", "common"]);

useDocumentTitle(translate("common:browse.deadlines"));

const { setTableURLState, tableURLState } = useTableURLState();
const [searchParams] = useSearchParams();

Expand Down
5 changes: 5 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Events/Events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import RenderedJsonField from "src/components/RenderedJsonField";
import Time from "src/components/Time";
import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams";
import { useAdvancedSearchArg } from "src/hooks/useAdvancedSearch";
import { useDocumentTitle } from "src/utils";

import { EventsFilters } from "./EventsFilters";

Expand Down Expand Up @@ -161,6 +162,10 @@ const {
export const Events = () => {
const { t: translate } = useTranslation(["browse", "common"]);
const { dagId, runId, taskId } = useParams();

// Only the standalone audit-log page owns the tab title; nested tabs inherit their parent page's title.
useDocumentTitle(dagId === undefined ? translate("common:browse.auditLog") : undefined);

const [searchParams] = useSearchParams();
const { setTableURLState, tableURLState } = useTableURLState();
const { pagination, sorting } = tableURLState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ import { useParams } from "react-router-dom";

import { DetailsLayout } from "src/layouts/Details/DetailsLayout";
import { useGridTiSummariesStream } from "src/queries/useGridTISummaries.ts";
import { useDocumentTitle } from "src/utils";

import { Header } from "./Header";

export const GroupTaskInstance = () => {
const { dagId = "", groupId = "", runId = "" } = useParams();
const { t: translate } = useTranslation("dag");

useDocumentTitle(groupId);

const { summariesByRunId } = useGridTiSummariesStream({ dagId, runIds: runId ? [runId] : [] });
const gridTISummaries = summariesByRunId.get(runId);
const taskInstance = gridTISummaries?.task_instances.find((ti) => ti.task_id === groupId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { TruncatedText } from "src/components/TruncatedText";
import { IconButton, RouterLink } from "src/components/ui";
import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams";
import { useAdvancedSearchArg } from "src/hooks/useAdvancedSearch";
import { useAutoRefresh } from "src/utils";
import { useAutoRefresh, useDocumentTitle } from "src/utils";
import { getHITLState, isHITLPending } from "src/utils/hitl";
import { getTaskInstanceLink } from "src/utils/links";

Expand Down Expand Up @@ -222,6 +222,10 @@ export const HITLTaskInstances = ({
}) => {
const { t: translate } = useTranslation("hitl");
const { dagId, runId, taskId } = useParams();

// Only the standalone required-actions page owns the tab title; nested tabs inherit their parent's.
useDocumentTitle(enableHITLReviewDrawer ? translate("common:browse.requiredActions") : undefined);

const { closeHITLReviewDrawer, isHITLReviewDrawerOpen, openHITLReviewDrawer, selectedDetail } =
useHITLReviewDrawer();
const [searchParams, setSearchParams] = useSearchParams();
Expand Down
5 changes: 4 additions & 1 deletion airflow-core/src/airflow/ui/src/pages/Jobs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { FilterBar } from "src/components/FilterBar";
import { StateBadge } from "src/components/StateBadge";
import Time from "src/components/Time";
import { SearchParamsKeys } from "src/constants/searchParams";
import { useFiltersHandler, type FilterableSearchParamsKeys } from "src/utils";
import { useDocumentTitle, useFiltersHandler, type FilterableSearchParamsKeys } from "src/utils";

const createColumns = (translate: TFunction): Array<ColumnDef<JobResponse>> => [
{
Expand Down Expand Up @@ -95,6 +95,9 @@ const jobsFilterKeys: Array<FilterableSearchParamsKeys> = [

export const Jobs = () => {
const { t: translate } = useTranslation(["admin", "common"]);

useDocumentTitle(translate("common:browse.jobs"));

const { setTableURLState, tableURLState } = useTableURLState();
const [searchParams] = useSearchParams();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ import { useParams } from "react-router-dom";
import { useDagRunServiceGetDagRun } from "openapi/queries";
import { DetailsLayout } from "src/layouts/Details/DetailsLayout";
import { useGridTiSummariesStream } from "src/queries/useGridTISummaries.ts";
import { useDocumentTitle } from "src/utils";

import { Header } from "./Header";

export const MappedTaskInstance = () => {
const { dagId = "", runId = "", taskId = "" } = useParams();
const { t: translate } = useTranslation("dag");

useDocumentTitle(taskId);

// Pass the run state so the summaries stream keeps auto-refreshing while the run is running;
// without it the Header and Details tab would freeze on the first fetch.
const { data: dagRun } = useDagRunServiceGetDagRun({ dagId, dagRunId: runId }, undefined, {
Expand Down
4 changes: 4 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Plugins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ import { usePluginServiceGetPlugins } from "openapi/queries";
import { DataTable } from "src/components/DataTable";
import { useTableURLState } from "src/components/DataTable/useTableUrlState";
import { ErrorAlert } from "src/components/ErrorAlert";
import { useDocumentTitle } from "src/utils";

import { PluginImportErrors } from "./Dashboard/Stats/PluginImportErrors";

export const Plugins = () => {
const { t: translate } = useTranslation(["admin", "common"]);

useDocumentTitle(translate("common:admin.Plugins"));

const { setTableURLState, tableURLState } = useTableURLState();
const { pagination } = tableURLState;
const { data, error } = usePluginServiceGetPlugins({
Expand Down
3 changes: 3 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Pools/Pools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { Select } from "src/components/ui";
import type { SearchParamsKeysType } from "src/constants/searchParams";
import { SearchParamsKeys } from "src/constants/searchParams";
import { useAdvancedSearch } from "src/hooks/useAdvancedSearch";
import { useDocumentTitle } from "src/utils";

import AddPoolButton from "./AddPoolButton";
import PoolBarCard from "./PoolBarCard";
Expand All @@ -47,6 +48,8 @@ const cardDef = (): CardDef<PoolResponse> => ({
export const Pools = () => {
const { t: translate } = useTranslation(["admin", "common"]);

useDocumentTitle(translate("common:admin.Pools"));

const poolSortOptions = createListCollection({
items: [
{ label: translate("pools.sort.asc"), value: "name" },
Expand Down
4 changes: 4 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { DataTable } from "src/components/DataTable";
import { useTableURLState } from "src/components/DataTable/useTableUrlState";
import { ErrorAlert } from "src/components/ErrorAlert";
import { urlRegex } from "src/constants/urlRegex";
import { useDocumentTitle } from "src/utils";

const createColumns = (translate: TFunction): Array<ColumnDef<ProviderResponse>> => [
{
Expand Down Expand Up @@ -77,6 +78,9 @@ const createColumns = (translate: TFunction): Array<ColumnDef<ProviderResponse>>

export const Providers = () => {
const { t: translate } = useTranslation(["admin", "common"]);

useDocumentTitle(translate("common:admin.Providers"));

const { setTableURLState, tableURLState } = useTableURLState();

const columns = createColumns(translate);
Expand Down
4 changes: 3 additions & 1 deletion airflow-core/src/airflow/ui/src/pages/Run/Run.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ import { useParams } from "react-router-dom";
import { useDagRunServiceGetDagRun } from "openapi/queries";
import { usePluginTabs } from "src/hooks/usePluginTabs";
import { DetailsLayout } from "src/layouts/Details/DetailsLayout";
import { isStatePending, useAutoRefresh } from "src/utils";
import { isStatePending, useAutoRefresh, useDocumentTitle } from "src/utils";

import { Header } from "./Header";

export const Run = () => {
const { t: translate } = useTranslation(["dag", "hitl"]);
const { dagId = "", runId = "" } = useParams();

useDocumentTitle(runId);

// Get external views with dag_run destination
const externalTabs = usePluginTabs("dag_run");

Expand Down
5 changes: 5 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Security.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
*/
import { Box } from "@chakra-ui/react";
import { useRef } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";

import { useAuthLinksServiceGetAuthMenus } from "openapi/queries";
import { ProgressBar } from "src/components/ui";
import { useDocumentTitle } from "src/utils";

import { ErrorPage } from "./Error";

Expand All @@ -33,6 +35,9 @@ const SANDBOX = "allow-scripts allow-same-origin allow-forms";

export const Security = () => {
const { page } = useParams();
const { t: translate } = useTranslation("common");

useDocumentTitle(translate("nav.security"));

const { data: authLinks, isLoading } = useAuthLinksServiceGetAuthMenus();

Expand Down
3 changes: 3 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/Task/Task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { usePluginTabs } from "src/hooks/usePluginTabs";
import { useRequiredActionTabs } from "src/hooks/useRequiredActionTabs";
import { DetailsLayout } from "src/layouts/Details/DetailsLayout";
import { useGridStructure } from "src/queries/useGridStructure.ts";
import { useDocumentTitle } from "src/utils";
import { getGroupTask } from "src/utils/groupTask";

import { GroupTaskHeader } from "./GroupTaskHeader";
Expand All @@ -37,6 +38,8 @@ export const Task = () => {
const { t: translate } = useTranslation(["dag", "hitl"]);
const { dagId = "", groupId, runId, taskId } = useParams();

useDocumentTitle(groupId ?? taskId);

// Get external views with task destination
const externalTabs = usePluginTabs("task");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ import { usePluginTabs } from "src/hooks/usePluginTabs";
import { useRequiredActionTabs } from "src/hooks/useRequiredActionTabs";
import { DetailsLayout } from "src/layouts/Details/DetailsLayout";
import { useGridTiSummariesStream } from "src/queries/useGridTISummaries.ts";
import { isStatePending, useAutoRefresh } from "src/utils";
import { isStatePending, useAutoRefresh, useDocumentTitle } from "src/utils";

import { Header } from "./Header";

export const TaskInstance = () => {
const { t: translate } = useTranslation(["dag", "common", "hitl"]);
const { dagId = "", mapIndex = "-1", runId = "", taskId = "" } = useParams();

useDocumentTitle(taskId);

// Get external views with task_instance destination
const externalTabs = usePluginTabs("task_instance");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { RouterLink } from "src/components/ui";
import { ActionBar } from "src/components/ui/ActionBar";
import { SearchParamsKeys, type SearchParamsKeysType } from "src/constants/searchParams";
import { useAdvancedSearchArg } from "src/hooks/useAdvancedSearch";
import { useAutoRefresh, isStatePending, renderDuration } from "src/utils";
import { useAutoRefresh, isStatePending, renderDuration, useDocumentTitle } from "src/utils";
import { getTaskInstanceLink } from "src/utils/links";

import BulkClearTaskInstancesButton from "./BulkClearTaskInstancesButton";
Expand Down Expand Up @@ -253,6 +253,10 @@ const taskInstanceColumns = ({
export const TaskInstances = () => {
const { t: translate } = useTranslation();
const { dagId, groupId, runId, taskId } = useParams();

// Only the standalone list page owns the tab title; nested tabs inherit their parent page's title.
useDocumentTitle(dagId === undefined ? translate("common:taskInstance_other") : undefined);

const [searchParams] = useSearchParams();

const { setTableURLState, tableURLState } = useTableURLState({
Expand Down
Loading
Loading