This is an automated email from the ASF dual-hosted git repository.
jscheffl 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 f924024a19a Revert "Feat: Support URL params for pre-filling Trigger
and Backfill forms (…" (#59769)
f924024a19a is described below
commit f924024a19a3c598a5f544eed4d14ee5b5ded96a
Author: Jens Scheffler <[email protected]>
AuthorDate: Tue Dec 23 19:46:15 2025 +0100
Revert "Feat: Support URL params for pre-filling Trigger and Backfill forms
(…" (#59769)
This reverts commit 907b4ef5340d8a489ea547a14ae2e6449b0b1a4e.
---
airflow-core/docs/core-concepts/params.rst | 52 --------
.../src/airflow/ui/src/components/ConfigForm.tsx | 6 +-
.../src/components/DagActions/RunBackfillForm.tsx | 47 +++-----
.../TriggerDag/TriggerDAGAdvancedOptions.tsx | 3 +-
.../src/components/TriggerDag/TriggerDAGForm.tsx | 132 ++++++++-------------
.../src/components/TriggerDag/TriggerDAGModal.tsx | 26 +---
.../airflow/ui/src/pages/Dag/Overview/Overview.tsx | 19 +--
.../src/airflow/ui/src/queries/useTrigger.ts | 4 +-
airflow-core/src/airflow/ui/src/router.tsx | 1 -
airflow-core/src/airflow/ui/src/utils/trigger.ts | 114 ------------------
docs/spelling_wordlist.txt | 1 -
11 files changed, 79 insertions(+), 326 deletions(-)
diff --git a/airflow-core/docs/core-concepts/params.rst
b/airflow-core/docs/core-concepts/params.rst
index ca3fb6849b3..cdcd150a73b 100644
--- a/airflow-core/docs/core-concepts/params.rst
+++ b/airflow-core/docs/core-concepts/params.rst
@@ -409,55 +409,3 @@ Disabling Runtime Param Modification
The ability to update params while triggering a Dag depends on the flag
``core.dag_run_conf_overrides_params``.
Setting this config to ``False`` will effectively turn your default params
into constants.
-
-Pre-populating Trigger Form via URL
------------------------------------
-
-To pre-populate values in the form when publishing a link to the trigger form
you can call the trigger URL ``/dags/<dag_name>/trigger/single`` or
``/dags/<dag_name>/trigger/backfill``,
-and add query parameters to the URL.
-
-There are two trigger form URLs available, each supporting a different set of
query parameters:
-
-* ``/trigger/single``:
- - ``conf`` - JSON configuration.
- - ``run_id`` - run identifier.
- - ``logical_date`` - execution date in ``YYYY-MM-DDTHH:mm:ss.SSS`` format.
Defaults to the current timestamp if not provided.
- - ``note`` - note attached to the DAG run.
-
-* ``/trigger/backfill``:
- - ``conf`` - JSON configuration, applied to all runs.
- - ``from_date`` - start of the backfill window in ``YYYY-MM-DDTHH:mm:ss``
format.
- - ``to_date`` - end of the backfill window in ``YYYY-MM-DDTHH:mm:ss`` format.
- - ``max_active_runs`` - maximum concurrent runs. Defaults to ``1``.
- - ``reprocess_behavior`` - determines how existing runs are reprocessed.
Supported values are:
-
- * ``failed`` - Missing and Errored Runs
- * ``completed`` - All Runs
- * ``none`` - Missing Runs
-
- - ``run_backwards`` - if set to true, the backfill is scheduled in reverse
order. Defaults to ``false``.
-
-The trigger form supports two different ways of providing ``conf`` values. The
available input methods are summarized in the table below:
-
-.. list-table:: ``conf`` parameter usage
- :header-rows: 1
- :widths: 15 35 55
-
- * - Form
- - Usage
- - Example
- * - JSON (explicit)
- - Provide the entire configuration as a JSON object.
- This form has higher priority if present.
- - ``/dags/{dag_id}/trigger/single?conf={"foo":"bar","x":123}``
- * - Key-value (implicit)
- - If ``conf`` is not specified, any query parameter that is not a
reserved keyword
- will be automatically collected into ``conf``.
- - ``/dags/{dag_id}/trigger/single?run_id=myrun&foo=bar&x=123``
- results in ``conf={"foo":"bar","x":"123"}``
-
-For example, you can pass the pathname and query like below:
-
-``/dags/{dag_id}/trigger/single?run_id=my_run_dag&logical_date=2025-09-06T12:34:56.789&conf={"foo":"bar"}¬e=run_note``
-
-``/dags/{dag_id}/trigger/backfill?from_date=2025-09-01T00:00:00&to_date=2025-09-03T23:59:59&conf={"abc":"loo"}&max_active_runs=2&reprocess_behavior=failed&run_backwards=true``
diff --git a/airflow-core/src/airflow/ui/src/components/ConfigForm.tsx
b/airflow-core/src/airflow/ui/src/components/ConfigForm.tsx
index b8c52106586..65adf1bfca3 100644
--- a/airflow-core/src/airflow/ui/src/components/ConfigForm.tsx
+++ b/airflow-core/src/airflow/ui/src/components/ConfigForm.tsx
@@ -35,7 +35,6 @@ type ConfigFormProps<T extends FieldValues = FieldValues> = {
date?: unknown;
};
readonly initialParamsDict: { paramsDict: ParamsSpec };
- readonly openAdvanced?: boolean;
readonly setErrors: React.Dispatch<
React.SetStateAction<{
conf?: string;
@@ -50,7 +49,6 @@ const ConfigForm = <T extends FieldValues = FieldValues>({
control,
errors,
initialParamsDict,
- openAdvanced = false,
setErrors,
setFormError,
}: ConfigFormProps<T>) => {
@@ -85,9 +83,7 @@ const ConfigForm = <T extends FieldValues = FieldValues>({
return (
<Accordion.Root
collapsible
- defaultValue={
- openAdvanced ? [flexibleFormDefaultSection, "advancedOptions"] :
[flexibleFormDefaultSection]
- }
+ defaultValue={[flexibleFormDefaultSection]}
mb={4}
overflow="visible"
size="lg"
diff --git
a/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx
b/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx
index 0be91753c22..2d3a99b4600 100644
--- a/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx
@@ -21,14 +21,8 @@ import dayjs from "dayjs";
import { useEffect, useState } from "react";
import { Controller, useForm, useWatch } from "react-hook-form";
import { useTranslation } from "react-i18next";
-import { useSearchParams } from "react-router-dom";
-import type {
- DAGResponse,
- DAGWithLatestDagRunsResponse,
- BackfillPostBody,
- ReprocessBehavior,
-} from "openapi/requests/types.gen";
+import type { BackfillPostBody, DAGResponse, DAGWithLatestDagRunsResponse }
from "openapi/requests/types.gen";
import { RadioCardItem, RadioCardLabel, RadioCardRoot } from
"src/components/ui/RadioCard";
import { reprocessBehaviors } from "src/constants/reprocessBehaviourParams";
import { useCreateBackfill } from "src/queries/useCreateBackfill";
@@ -36,12 +30,11 @@ import { useCreateBackfillDryRun } from
"src/queries/useCreateBackfillDryRun";
import { useDagParams } from "src/queries/useDagParams";
import { useParamStore } from "src/queries/useParamStore";
import { useTogglePause } from "src/queries/useTogglePause";
-import { getTriggerConf } from "src/utils/trigger";
-import type { DagRunTriggerParams } from "src/utils/trigger";
import ConfigForm from "../ConfigForm";
import { DateTimeInput } from "../DateTimeInput";
import { ErrorAlert } from "../ErrorAlert";
+import type { DagRunTriggerParams } from "../TriggerDag/TriggerDAGForm";
import { Checkbox } from "../ui/Checkbox";
import { getInlineMessage } from "./inlineMessage";
@@ -59,19 +52,16 @@ const RunBackfillForm = ({ dag, onClose }:
RunBackfillFormProps) => {
const [formError, setFormError] = useState(false);
const initialParamsDict = useDagParams(dag.dag_id, true);
const { conf } = useParamStore();
- const [searchParams] = useSearchParams();
- const reservedKeys = ["from_date", "to_date", "max_active_runs",
"reprocess_behavior", "run_backwards"];
- const urlConf = getTriggerConf(searchParams, reservedKeys);
- const { control, handleSubmit, reset } = useForm<BackfillFormProps>({
+ const { control, handleSubmit, reset, watch } = useForm<BackfillFormProps>({
defaultValues: {
- conf: urlConf === "{}" ? conf || "{}" : urlConf,
+ conf,
dag_id: dag.dag_id,
- from_date: searchParams.get("from_date") ?? "",
- max_active_runs: parseInt(searchParams.get("max_active_runs") ?? "1",
10) || 1,
- reprocess_behavior: (searchParams.get("reprocess_behavior") ?? "none")
as ReprocessBehavior,
- run_backwards: searchParams.get("run_backwards") === "true",
+ from_date: "",
+ max_active_runs: 1,
+ reprocess_behavior: "none",
+ run_backwards: false,
run_on_latest_version: true,
- to_date: searchParams.get("to_date") ?? "",
+ to_date: "",
},
mode: "onBlur",
});
@@ -101,13 +91,16 @@ const RunBackfillForm = ({ dag, onClose }:
RunBackfillFormProps) => {
if (Boolean(dateValidationError)) {
setErrors((prev) => ({ ...prev, date: dateValidationError }));
}
- if (Boolean(conf) && urlConf === "{}") {
- reset((prev) => ({ ...prev, conf }));
+ }, [dateValidationError]);
+ useEffect(() => {
+ if (conf) {
+ reset((prevValues) => ({ ...prevValues, conf }));
}
- }, [dateValidationError, conf, reset, urlConf]);
-
- const noDataInterval = !Boolean(values.from_date) ||
!Boolean(values.to_date);
- const dataIntervalInvalid =
dayjs(values.from_date).isAfter(dayjs(values.to_date));
+ }, [conf, reset]);
+ const dataIntervalStart = watch("from_date");
+ const dataIntervalEnd = watch("to_date");
+ const noDataInterval = !Boolean(dataIntervalStart) ||
!Boolean(dataIntervalEnd);
+ const dataIntervalInvalid =
dayjs(dataIntervalStart).isAfter(dayjs(dataIntervalEnd));
const onSubmit = (fdata: BackfillFormProps) => {
if (unpause && dag.is_paused) {
@@ -246,10 +239,6 @@ const RunBackfillForm = ({ dag, onClose }:
RunBackfillFormProps) => {
control={control}
errors={errors}
initialParamsDict={initialParamsDict}
- openAdvanced={
- urlConf !== "{}" ||
- ["max_active_runs", "reprocess_behavior",
"run_backwards"].some((key) => searchParams.has(key))
- }
setErrors={setErrors}
setFormError={setFormError}
/>
diff --git
a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGAdvancedOptions.tsx
b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGAdvancedOptions.tsx
index 70c0b2a91b2..b8d3fe2b9f4 100644
---
a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGAdvancedOptions.tsx
+++
b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGAdvancedOptions.tsx
@@ -20,9 +20,8 @@ import { Input, Field, Stack } from "@chakra-ui/react";
import { Controller, type Control } from "react-hook-form";
import { useTranslation } from "react-i18next";
-import type { DagRunTriggerParams } from "src/utils/trigger";
-
import EditableMarkdown from "./EditableMarkdown";
+import type { DagRunTriggerParams } from "./TriggerDAGForm";
type TriggerDAGAdvancedOptionsProps = {
readonly control: Control<DagRunTriggerParams>;
diff --git
a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
index 4bad37b767b..cd291acb09e 100644
--- a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
@@ -18,26 +18,16 @@
*/
import { Button, Box, Spacer, HStack, Field, Stack, Text, VStack } from
"@chakra-ui/react";
import dayjs from "dayjs";
-import { useEffect, useState, useRef, useMemo } from "react";
+import { useEffect, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { FiPlay } from "react-icons/fi";
-import { useSearchParams } from "react-router-dom";
import { useDagParams } from "src/queries/useDagParams";
import { useParamStore } from "src/queries/useParamStore";
import { useTogglePause } from "src/queries/useTogglePause";
import { useTrigger } from "src/queries/useTrigger";
import { DEFAULT_DATETIME_FORMAT } from "src/utils/datetimeUtils";
-import {
- getTriggerConf,
- mergeUrlParams,
- getUpdatedParamsDict,
- type DagRunTriggerParams,
- dataIntervalModeOptions,
- extractParamValues,
- type TriggerDAGFormProps,
-} from "src/utils/trigger";
import ConfigForm from "../ConfigForm";
import { DateTimeInput } from "../DateTimeInput";
@@ -46,6 +36,33 @@ import { Checkbox } from "../ui/Checkbox";
import { RadioCardItem, RadioCardRoot } from "../ui/RadioCard";
import TriggerDAGAdvancedOptions from "./TriggerDAGAdvancedOptions";
+type TriggerDAGFormProps = {
+ readonly dagDisplayName: string;
+ readonly dagId: string;
+ readonly hasSchedule: boolean;
+ readonly isPaused: boolean;
+ readonly onClose: () => void;
+ readonly open: boolean;
+};
+
+type DataIntervalMode = "auto" | "manual";
+
+export type DagRunTriggerParams = {
+ conf: string;
+ dagRunId: string;
+ dataIntervalEnd: string;
+ dataIntervalMode: DataIntervalMode;
+ dataIntervalStart: string;
+ logicalDate: string;
+ note: string;
+ partitionKey: string | undefined;
+};
+
+const dataIntervalModeOptions: Array<{ label: string; value: DataIntervalMode
}> = [
+ { label: "components:triggerDag.dataIntervalAuto", value: "auto" },
+ { label: "components:triggerDag.dataIntervalManual", value: "manual" },
+];
+
const TriggerDAGForm = ({
dagDisplayName,
dagId,
@@ -59,84 +76,38 @@ const TriggerDAGForm = ({
const [formError, setFormError] = useState(false);
const initialParamsDict = useDagParams(dagId, open);
const { error: errorTrigger, isPending, triggerDagRun } = useTrigger({
dagId, onSuccessConfirm: onClose });
- const { conf, setParamsDict } = useParamStore();
+ const { conf } = useParamStore();
const [unpause, setUnpause] = useState(true);
- const [searchParams] = useSearchParams();
- const urlConf = getTriggerConf(searchParams, ["run_id", "logical_date",
"note"]);
- const urlRunId = searchParams.get("run_id") ?? "";
- const urlDate = searchParams.get("logical_date");
- const urlNote = searchParams.get("note") ?? "";
const { mutate: togglePause } = useTogglePause({ dagId });
- const defaultsRef = useRef<DagRunTriggerParams | undefined>(undefined);
- const isSyncedRef = useRef(false);
-
- const cleanInitialParams = useMemo(
- () => extractParamValues(initialParamsDict.paramsDict as Record<string,
unknown>),
- [initialParamsDict.paramsDict],
- );
- const { control, getValues, handleSubmit, reset, watch } =
useForm<DagRunTriggerParams>({
+ const { control, handleSubmit, reset, watch } =
useForm<DagRunTriggerParams>({
defaultValues: {
- ...initialParamsDict,
- conf: urlConf === "{}" ? conf || "{}" : urlConf,
- dagRunId: urlRunId,
+ conf,
+ dagRunId: "",
dataIntervalEnd: "",
dataIntervalMode: "auto",
dataIntervalStart: "",
// Default logical date to now, show it in the selected timezone
- logicalDate: urlDate ?? dayjs().format(DEFAULT_DATETIME_FORMAT),
- note: urlNote,
- params: cleanInitialParams,
+ logicalDate: dayjs().format(DEFAULT_DATETIME_FORMAT),
+ note: "",
partitionKey: undefined,
},
});
// Automatically reset form when conf is fetched
useEffect(() => {
- if (defaultsRef.current === undefined &&
Object.keys(cleanInitialParams).length > 0) {
- const current = getValues();
-
- defaultsRef.current = {
- ...current,
- params: cleanInitialParams,
- };
- }
- }, [getValues, cleanInitialParams]);
-
- useEffect(() => {
- if (defaultsRef.current === undefined) {
- return;
+ if (conf) {
+ reset((prevValues) => ({
+ ...prevValues,
+ conf,
+ }));
}
+ }, [conf, reset]);
- if (isSyncedRef.current) {
- return;
- }
-
- if (urlConf === "{}") {
- if (conf) {
- reset((prev) => ({ ...prev, conf }));
- }
- isSyncedRef.current = true;
-
- return;
- }
-
- const mergedValues = mergeUrlParams(urlConf, defaultsRef.current.params ??
{});
-
- reset({
- ...defaultsRef.current,
- conf: JSON.stringify(mergedValues, undefined, 2),
- dagRunId: urlRunId || defaultsRef.current.dagRunId,
- logicalDate: urlDate ?? defaultsRef.current.logicalDate,
- note: urlNote || defaultsRef.current.note,
- });
-
- setParamsDict(getUpdatedParamsDict(initialParamsDict.paramsDict,
mergedValues));
- isSyncedRef.current = true;
- }, [urlConf, urlRunId, urlDate, urlNote, initialParamsDict, reset,
setParamsDict, conf]);
-
- const resetDateError = () => setErrors((prev) => ({ ...prev, date: undefined
}));
+ const resetDateError = () => {
+ setErrors((prev) => ({ ...prev, date: undefined }));
+ };
const dataIntervalMode = watch("dataIntervalMode");
const dataIntervalStart = watch("dataIntervalStart");
@@ -145,17 +116,17 @@ const TriggerDAGForm = ({
const dataIntervalInvalid =
dataIntervalMode === "manual" &&
(noDataInterval ||
dayjs(dataIntervalStart).isAfter(dayjs(dataIntervalEnd)));
+
const onSubmit = (data: DagRunTriggerParams) => {
if (unpause && isPaused) {
- togglePause({ dagId, requestBody: { is_paused: false } });
+ togglePause({
+ dagId,
+ requestBody: {
+ is_paused: false,
+ },
+ });
}
-
- const finalParams = mergeUrlParams(data.conf, data.params ?? {});
-
- triggerDagRun({
- ...data,
- conf: JSON.stringify(finalParams),
- });
+ triggerDagRun(data);
};
return (
@@ -248,7 +219,6 @@ const TriggerDAGForm = ({
control={control}
errors={errors}
initialParamsDict={initialParamsDict}
- openAdvanced={urlConf !== "{}" || Boolean(urlRunId) ||
Boolean(urlDate) || Boolean(urlNote)}
setErrors={setErrors}
setFormError={setFormError}
>
diff --git
a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGModal.tsx
b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGModal.tsx
index aaf9e22db52..9eb3e00a0e1 100644
--- a/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGModal.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TriggerDag/TriggerDAGModal.tsx
@@ -17,9 +17,8 @@
* under the License.
*/
import { Heading, VStack, HStack, Spinner, Center, Text } from
"@chakra-ui/react";
-import React, { useState, useEffect } from "react";
+import React, { useState } from "react";
import { useTranslation } from "react-i18next";
-import { useParams, useNavigate } from "react-router-dom";
import { useDagServiceGetDag } from "openapi/queries";
import { Dialog, Tooltip } from "src/components/ui";
@@ -49,11 +48,7 @@ const TriggerDAGModal: React.FC<TriggerDAGModalProps> = ({
open,
}) => {
const { t: translate } = useTranslation("components");
- const { mode } = useParams();
- const navigate = useNavigate();
- const [runMode, setRunMode] = useState<RunMode>(
- mode === RunMode.BACKFILL ? RunMode.BACKFILL : RunMode.SINGLE,
- );
+ const [runMode, setRunMode] = useState<RunMode>(RunMode.SINGLE);
const {
data: dag,
isError,
@@ -68,17 +63,6 @@ const TriggerDAGModal: React.FC<TriggerDAGModalProps> = ({
},
);
- useEffect(() => {
- if (mode === RunMode.BACKFILL) {
- setRunMode(RunMode.BACKFILL);
- } else {
- setRunMode(RunMode.SINGLE);
- }
- }, [mode]);
- const handleModeChange = (value: string) => {
- setRunMode(value as RunMode);
- navigate(`/dags/${dagId}/trigger/${value}`, { replace: true });
- };
const hasSchedule = dag?.timetable_summary !== null;
const maxDisplayLength = 59; // hard-coded length to prevent dag name
overflowing the modal
const nameOverflowing = dagDisplayName.length > maxDisplayLength;
@@ -114,10 +98,8 @@ const TriggerDAGModal: React.FC<TriggerDAGModalProps> = ({
{dag ? (
<RadioCardRoot
my={4}
- onValueChange={(details) => {
- if (details.value !== null) {
- handleModeChange(details.value);
- }
+ onChange={(event) => {
+ setRunMode((event.target as HTMLInputElement).value as
RunMode);
}}
value={runMode}
>
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx
b/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx
index 5dd2e2fa949..8cebcc4ba0b 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx
@@ -20,13 +20,12 @@ import { Box, HStack, Skeleton } from "@chakra-ui/react";
import dayjs from "dayjs";
import { lazy, useState, Suspense } from "react";
import { useTranslation } from "react-i18next";
-import { useParams, useNavigate } from "react-router-dom";
+import { useParams } from "react-router-dom";
import { useLocalStorage } from "usehooks-ts";
import {
useAssetServiceGetAssetEvents,
useDagRunServiceGetDagRuns,
- useDagServiceGetDag,
useTaskInstanceServiceGetTaskInstances,
} from "openapi/queries";
import { AssetEvents } from "src/components/Assets/AssetEvents";
@@ -34,7 +33,6 @@ import { DurationChart } from "src/components/DurationChart";
import { NeedsReviewButton } from "src/components/NeedsReviewButton";
import TimeRangeSelector from "src/components/TimeRangeSelector";
import { TrendCountButton } from "src/components/TrendCountButton";
-import TriggerDAGModal from "src/components/TriggerDag/TriggerDAGModal";
import { SearchParamsKeys } from "src/constants/searchParams";
import { useGridRuns } from "src/queries/useGridRuns.ts";
@@ -44,10 +42,7 @@ const defaultHour = "24";
export const Overview = () => {
const { t: translate } = useTranslation("dag");
- const { dagId, mode } = useParams();
- const navigate = useNavigate();
-
- const { data: dagData } = useDagServiceGetDag({ dagId: dagId ?? "" });
+ const { dagId } = useParams();
const now = dayjs();
const [startDate, setStartDate] = useState(now.subtract(Number(defaultHour),
"hour").toISOString());
@@ -145,16 +140,6 @@ export const Overview = () => {
<Suspense fallback={<Skeleton height="100px" width="full" />}>
<FailedLogs failedTasks={failedTasks} />
</Suspense>
-
- {dagData ? (
- <TriggerDAGModal
- dagDisplayName={dagData.dag_display_name}
- dagId={dagData.dag_id}
- isPaused={dagData.is_paused}
- onClose={() => navigate(`/dags/${dagId}`)}
- open={Boolean(mode)}
- />
- ) : null}
</Box>
);
};
diff --git a/airflow-core/src/airflow/ui/src/queries/useTrigger.ts
b/airflow-core/src/airflow/ui/src/queries/useTrigger.ts
index f395da3ca1c..de2baede248 100644
--- a/airflow-core/src/airflow/ui/src/queries/useTrigger.ts
+++ b/airflow-core/src/airflow/ui/src/queries/useTrigger.ts
@@ -29,8 +29,8 @@ import {
UseGridServiceGetGridRunsKeyFn,
} from "openapi/queries";
import type { TriggerDagRunResponse } from "openapi/requests/types.gen";
+import type { DagRunTriggerParams } from
"src/components/TriggerDag/TriggerDAGForm";
import { toaster } from "src/components/ui";
-import type { DagRunTriggerParams } from "src/utils/trigger";
export const useTrigger = ({ dagId, onSuccessConfirm }: { dagId: string;
onSuccessConfirm: () => void }) => {
const queryClient = useQueryClient();
@@ -107,7 +107,7 @@ export const useTrigger = ({ dagId, onSuccessConfirm }: {
dagId: string; onSucce
data_interval_start: formattedDataIntervalStart,
logical_date: formattedLogicalDate,
note: checkNote,
- partition_key: dagRunRequestBody.partitionKey ?? undefined,
+ partition_key: dagRunRequestBody.partitionKey ?? null,
},
});
};
diff --git a/airflow-core/src/airflow/ui/src/router.tsx
b/airflow-core/src/airflow/ui/src/router.tsx
index faaff2bfa96..5c3ddc76174 100644
--- a/airflow-core/src/airflow/ui/src/router.tsx
+++ b/airflow-core/src/airflow/ui/src/router.tsx
@@ -160,7 +160,6 @@ export const routerConfig = [
{
children: [
{ element: <Overview />, index: true },
- { element: <Overview />, path: "trigger/:mode?" },
{ element: <DagRuns />, path: "runs" },
{ element: <Tasks />, path: "tasks" },
{ element: <Calendar />, path: "calendar" },
diff --git a/airflow-core/src/airflow/ui/src/utils/trigger.ts
b/airflow-core/src/airflow/ui/src/utils/trigger.ts
deleted file mode 100644
index 1fd7c963b91..00000000000
--- a/airflow-core/src/airflow/ui/src/utils/trigger.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-/*!
- * 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.
- */
-
-// Helper to extract configuration from URL search params
-export const getTriggerConf = (searchParams: URLSearchParams, reservedKeys:
Array<string>) => {
- const confParam = searchParams.get("conf");
-
- // 1. If the user provided direct JSON 'conf' param (e.g.,
?conf={"foo":"bar"})
- if (confParam !== null) {
- try {
- const parsed = JSON.parse(confParam) as unknown;
-
- return JSON.stringify(parsed, undefined, 2);
- } catch {
- // Ignore parsing errors
- }
- }
-
- // 2. If the user provided individual key-value params (e.g.,
?foo=bar&run_id=123)
- const collected: Record<string, unknown> = {};
-
- searchParams.forEach((value, key) => {
- // Do not include reserved keys (like run_id, date) in the config, as they
belong to specific form fields
- if (!reservedKeys.includes(key) && key !== "conf") {
- collected[key] = value;
- }
- });
-
- return Object.keys(collected).length > 0 ? JSON.stringify(collected,
undefined, 2) : "{}";
-};
-
-export type DataIntervalMode = "auto" | "manual";
-
-export type DagRunTriggerParams = {
- conf: string;
- dagRunId: string;
- dataIntervalEnd: string;
- dataIntervalMode: DataIntervalMode;
- dataIntervalStart: string;
- logicalDate: string;
- note: string;
- params?: Record<string, unknown>;
- partitionKey: string | undefined;
-};
-export type TriggerDAGFormProps = {
- readonly dagDisplayName: string;
- readonly dagId: string;
- readonly hasSchedule: boolean;
- readonly isPaused: boolean;
- readonly onClose: () => void;
- readonly open: boolean;
-};
-export const dataIntervalModeOptions: Array<{ label: string; value:
DataIntervalMode }> = [
- { label: "components:triggerDag.dataIntervalAuto", value: "auto" },
- { label: "components:triggerDag.dataIntervalManual", value: "manual" },
-];
-
-export const extractParamValues = (obj: Record<string, unknown>) => {
- const out: Record<string, unknown> = {};
-
- Object.entries(obj).forEach(([key, val]) => {
- if (val !== null && typeof val === "object" && "value" in val) {
- out[key] = (val as { value: unknown }).value;
- } else if (val !== null && typeof val === "object" && "default" in val) {
- out[key] = (val as { default: unknown }).default;
- } else {
- out[key] = val;
- }
- });
-
- return out;
-};
-
-export const mergeUrlParams = (urlConf: string, baseParams: Record<string,
unknown>) => {
- try {
- const parsed = urlConf === "{}" ? {} : (JSON.parse(urlConf) as
Record<string, unknown>);
-
- return { ...baseParams, ...parsed };
- } catch {
- return baseParams;
- }
-};
-export type ParamEntry = {
- [key: string]: unknown;
- value: unknown;
-};
-export const getUpdatedParamsDict = <T>(paramsDict: T, mergedValues:
Record<string, unknown>): T => {
- const updated = structuredClone(paramsDict);
- const record = updated as Record<string, { value: unknown }>;
-
- Object.entries(mergedValues).forEach(([key, val]) => {
- if (record[key] !== undefined) {
- record[key].value = val;
- }
- });
-
- return updated;
-};
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 9cd8c459c19..a3e10044b57 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -1523,7 +1523,6 @@ replicaSet
repo
repos
repr
-reprocessed
req
reqs
requeue