| @@ -637,7 +637,10 @@ const TimeLeaveInputTable: React.FC<Props> = ({ | |||||
| setValue(day, newEntries); | setValue(day, newEntries); | ||||
| if (entries.some((e) => e._isNew)) { | if (entries.some((e) => e._isNew)) { | ||||
| setError(day, { message: "There are some unsaved entries." }); | |||||
| setError(day, { | |||||
| message: "There are some unsaved entries.", | |||||
| type: "custom", | |||||
| }); | |||||
| } else { | } else { | ||||
| clearErrors(day); | clearErrors(day); | ||||
| } | } | ||||
| @@ -39,6 +39,7 @@ import DateHoursList from "../DateHoursTable/DateHoursList"; | |||||
| import TimeLeaveInputTable from "./TimeLeaveInputTable"; | import TimeLeaveInputTable from "./TimeLeaveInputTable"; | ||||
| import TimeLeaveMobileEntry from "./TimeLeaveMobileEntry"; | import TimeLeaveMobileEntry from "./TimeLeaveMobileEntry"; | ||||
| import { Task } from "@/app/api/tasks"; | import { Task } from "@/app/api/tasks"; | ||||
| import waitForCondition from "../utils/waitFor"; | |||||
| interface Props { | interface Props { | ||||
| isOpen: boolean; | isOpen: boolean; | ||||
| @@ -240,9 +241,14 @@ const TimeLeaveModal: React.FC<Props> = ({ | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| startIcon={<Check />} | startIcon={<Check />} | ||||
| type="submit" | |||||
| onClick={() => { | |||||
| onClick={async () => { | |||||
| await waitForCondition(async () => { | |||||
| return !Object.values(formProps.formState.errors).some( | |||||
| (err) => err?.type === "custom", | |||||
| ); | |||||
| }); | |||||
| formProps.clearErrors(); | formProps.clearErrors(); | ||||
| formProps.handleSubmit(onSubmit)(); | |||||
| }} | }} | ||||
| > | > | ||||
| {t("Save")} | {t("Save")} | ||||
| @@ -0,0 +1,30 @@ | |||||
| /** | |||||
| * Wait until a condition to be true with a default timeout of 1 second (and checking every 100ms). | |||||
| */ | |||||
| export const waitForCondition = async ( | |||||
| condition: () => Promise<boolean>, | |||||
| waitOptions: { | |||||
| timeout: number; | |||||
| interval: number; | |||||
| } = { timeout: 1000, interval: 100 }, | |||||
| ) => { | |||||
| const startTime = Date.now(); | |||||
| const check = async () => { | |||||
| if (await condition()) { | |||||
| return; | |||||
| } else { | |||||
| if (Date.now() - startTime < waitOptions.timeout) { | |||||
| return new Promise((resolve) => { | |||||
| setTimeout(() => { | |||||
| resolve(check()); | |||||
| }, waitOptions.interval); | |||||
| }); | |||||
| } | |||||
| } | |||||
| }; | |||||
| return check(); | |||||
| }; | |||||
| export default waitForCondition; | |||||