Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data Interval Date validation of trigger Dag form #45223

Merged
merged 6 commits into from
Dec 26, 2024
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
56 changes: 22 additions & 34 deletions airflow/ui/src/components/TriggerDag/TriggerDAGForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,18 @@ export type DagRunTriggerParams = {
const TriggerDAGForm = ({ dagId, onClose, open }: TriggerDAGFormProps) => {
const [errors, setErrors] = useState<{ conf?: string; date?: unknown }>({});
const conf = useDagParams(dagId, open);
const { error: errorTrigger, isPending, triggerDagRun } = useTrigger(onClose);
const {
dateValidationError,
error: errorTrigger,
isPending,
triggerDagRun,
} = useTrigger({ onSuccessConfirm: onClose });

const {
control,
formState: { isDirty },
handleSubmit,
reset,
setValue,
watch,
} = useForm<DagRunTriggerParams>({
defaultValues: {
Expand All @@ -74,28 +78,27 @@ const TriggerDAGForm = ({ dagId, onClose, open }: TriggerDAGFormProps) => {
}
}, [conf, reset]);

useEffect(() => {
if (Boolean(dateValidationError)) {
setErrors((prev) => ({ ...prev, date: dateValidationError }));
}
}, [dateValidationError]);

const dataIntervalStart = watch("dataIntervalStart");
const dataIntervalEnd = watch("dataIntervalEnd");

const handleReset = () => {
setErrors({ conf: undefined, date: undefined });
reset();
reset({
conf,
dagRunId: "",
dataIntervalEnd: "",
dataIntervalStart: "",
note: "",
});
};

const onSubmit = (data: DagRunTriggerParams) => {
if (Boolean(data.dataIntervalStart) !== Boolean(data.dataIntervalEnd)) {
setErrors((prev) => ({
...prev,
date: {
body: {
detail:
"Either both Data Interval Start and End must be provided, or both must be empty.",
},
},
}));

return;
}
triggerDagRun(dagId, data);
};

Expand All @@ -119,23 +122,8 @@ const TriggerDAGForm = ({ dagId, onClose, open }: TriggerDAGFormProps) => {
}
};

const validateDates = (
fieldName: "dataIntervalEnd" | "dataIntervalStart",
) => {
const startDate = dataIntervalStart
? new Date(dataIntervalStart)
: undefined;
const endDate = dataIntervalEnd ? new Date(dataIntervalEnd) : undefined;

const resetDateError = () => {
setErrors((prev) => ({ ...prev, date: undefined }));

if (startDate && endDate) {
if (fieldName === "dataIntervalStart" && startDate > endDate) {
setValue("dataIntervalStart", dataIntervalEnd);
} else if (fieldName === "dataIntervalEnd" && endDate < startDate) {
setValue("dataIntervalEnd", dataIntervalStart);
}
}
};

const { colorMode } = useColorMode();
Expand All @@ -160,7 +148,7 @@ const TriggerDAGForm = ({ dagId, onClose, open }: TriggerDAGFormProps) => {
<Input
{...field}
max={dataIntervalEnd || undefined}
onBlur={() => validateDates("dataIntervalStart")}
onBlur={resetDateError}
placeholder="yyyy-mm-ddThh:mm"
size="sm"
type="datetime-local"
Expand All @@ -180,7 +168,7 @@ const TriggerDAGForm = ({ dagId, onClose, open }: TriggerDAGFormProps) => {
<Input
{...field}
min={dataIntervalStart || undefined}
onBlur={() => validateDates("dataIntervalEnd")}
onBlur={resetDateError}
placeholder="yyyy-mm-ddThh:mm"
size="sm"
type="datetime-local"
Expand Down
61 changes: 48 additions & 13 deletions airflow/ui/src/queries/useTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@ import {
import type { DagRunTriggerParams } from "src/components/TriggerDag/TriggerDAGForm";
import { toaster } from "src/components/ui";

export const useTrigger = (onClose: () => void) => {
export const useTrigger = ({
onSuccessConfirm,
}: {
onSuccessConfirm: () => void;
}) => {
const queryClient = useQueryClient();
const [error, setError] = useState<unknown>(undefined);

const [dateValidationError, setDateValidationError] =
useState<unknown>(undefined);

const onSuccess = async () => {
const queryKeys = [
useDagServiceGetDagsKey,
Expand All @@ -43,14 +50,13 @@ export const useTrigger = (onClose: () => void) => {
queryKeys.map((key) =>
queryClient.invalidateQueries({ queryKey: [key] }),
),
).then(() => {
toaster.create({
description: "DAG run has been successfully triggered.",
title: "DAG Run Request Submitted",
type: "success",
});
onClose();
);
toaster.create({
description: "DAG run has been successfully triggered.",
title: "DAG Run Request Submitted",
type: "success",
});
onSuccessConfirm();
};

const onError = (_error: unknown) => {
Expand All @@ -71,13 +77,42 @@ export const useTrigger = (onClose: () => void) => {
unknown
>;

const formattedDataIntervalStart = dagRunRequestBody.dataIntervalStart
? new Date(dagRunRequestBody.dataIntervalStart).toISOString()
const DataIntervalStart = dagRunRequestBody.dataIntervalStart
? new Date(dagRunRequestBody.dataIntervalStart)
: undefined;
const formattedDataIntervalEnd = dagRunRequestBody.dataIntervalEnd
? new Date(dagRunRequestBody.dataIntervalEnd).toISOString()
const DataIntervalEnd = dagRunRequestBody.dataIntervalEnd
? new Date(dagRunRequestBody.dataIntervalEnd)
: undefined;

if (Boolean(DataIntervalStart) !== Boolean(DataIntervalEnd)) {
setDateValidationError({
body: {
detail:
"Either both Data Interval Start Date and End Date must be provided, or both must be empty.",
},
});

return;
}

if (DataIntervalStart && DataIntervalEnd) {
if (DataIntervalStart > DataIntervalEnd) {
setDateValidationError({
body: {
detail:
"Data Interval Start Date must be less than or equal to Data Interval End Date.",
},
});

return;
}
}

const formattedDataIntervalStart =
DataIntervalStart?.toISOString() ?? undefined;
const formattedDataIntervalEnd =
DataIntervalEnd?.toISOString() ?? undefined;

const checkDagRunId =
dagRunRequestBody.dagRunId === ""
? undefined
Expand All @@ -97,5 +132,5 @@ export const useTrigger = (onClose: () => void) => {
});
};

return { error, isPending, triggerDagRun };
return { dateValidationError, error, isPending, triggerDagRun };
};