You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by js...@apache.org on 2025/12/23 17:10:17 UTC

(airflow) branch revert-59231-feature/trigger-url-params created (now 56c4855a59f)

This is an automated email from the ASF dual-hosted git repository.

jscheffl pushed a change to branch revert-59231-feature/trigger-url-params
in repository https://gitbox.apache.org/repos/asf/airflow.git


      at 56c4855a59f Revert "Feat: Support URL params for pre-filling Trigger and Backfill forms (…"

This branch includes the following new commits:

     new 56c4855a59f Revert "Feat: Support URL params for pre-filling Trigger and Backfill forms (…"

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(airflow) 01/01: Revert "Feat: Support URL params for pre-filling Trigger and Backfill forms (…"

Posted by js...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jscheffl pushed a commit to branch revert-59231-feature/trigger-url-params
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 56c4855a59ffcf3a2d290e4fd18fba5a229f898b
Author: Jens Scheffler <95...@users.noreply.github.com>
AuthorDate: Tue Dec 23 18:10:06 2025 +0100

    Revert "Feat: Support URL params for pre-filling Trigger and Backfill forms (…"
    
    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"}&note=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