Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Commit 8fb6314

Browse files
committed
fix: reservation unit archive double toasting
1 parent 733d3bc commit 8fb6314

2 files changed

Lines changed: 87 additions & 72 deletions

File tree

apps/admin-ui/src/i18n/messages.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,15 @@ const translations: ITranslations = {
232232
RESERVATION_UNIT_PRICINGS_INVALID_PRICES: [
233233
"Hinnoittelussa on virheellisiä hintoja",
234234
],
235+
RESERVATION_UNIT_MISSING_TRANSLATIONS: [
236+
"Varausyksiköllä puuttuu käännökset",
237+
],
238+
RESERVATION_UNIT_MISSING_SPACES_OR_RESOURCES: [
239+
"Varausyksiköllä ei ole tiloja tai resursseja",
240+
],
241+
RESERVATION_UNIT_MISSING_RESERVATION_UNIT_TYPE: [
242+
"Varausyksiköllä ei ole varausyksikkötyyppiä",
243+
],
235244
},
236245
descriptive: {
237246
"Reservation overlaps with reservation before due to buffer time.": [

apps/admin-ui/src/spa/ReservationUnit/edit/index.tsx

Lines changed: 78 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ import {
7474
import { ButtonLikeLink } from "@/component/ButtonLikeLink";
7575
import { SeasonalSection } from "./SeasonalSection";
7676
import { getValidationErrors } from "common/src/apolloUtils";
77+
import { getReservationUnitUrl, getUnitUrl } from "@/common/urls";
7778

7879
const RichTextInput = dynamic(
7980
() => import("../../../component/RichTextInput"),
@@ -1709,106 +1710,111 @@ function ReservationUnitEditor({
17091710
}));
17101711

17111712
// ----------------------------- Callbacks ----------------------------------
1713+
// unsafe because the handleSubmit doesn't pass return value (so throw is the only way to manipulate control flow)
17121714
const onSubmit = async (formValues: ReservationUnitEditFormValues) => {
17131715
const { pk, ...input } = transformReservationUnit(formValues);
1714-
try {
1715-
const promise =
1716-
pk != null
1717-
? updateMutation({ variables: { input: { ...input, pk } } })
1718-
: createMutation({
1719-
variables: { input: { ...input, unit: unitPk } },
1720-
});
1721-
1722-
const { data, errors: mutationErrors } = await promise;
1723-
if (mutationErrors != null) {
1724-
errorToast({
1725-
text: t("ReservationUnitEditor.saveFailed", {
1726-
error: mutationErrors,
1727-
}),
1728-
});
1729-
return undefined;
1730-
}
1716+
const promise =
1717+
pk != null
1718+
? updateMutation({ variables: { input: { ...input, pk } } })
1719+
: createMutation({
1720+
variables: { input: { ...input, unit: unitPk } },
1721+
});
17311722

1732-
const getPk = (d: typeof data) => {
1733-
if (d == null) {
1734-
return null;
1735-
}
1736-
if ("updateReservationUnit" in d) {
1737-
return d.updateReservationUnit?.pk ?? null;
1738-
}
1739-
if ("createReservationUnit" in d) {
1740-
return d.createReservationUnit?.pk ?? null;
1741-
}
1723+
const { data, errors: mutationErrors } = await promise;
1724+
if (mutationErrors != null) {
1725+
const msg = t("ReservationUnitEditor.saveFailed", {
1726+
error: mutationErrors,
1727+
});
1728+
throw new Error(msg);
1729+
}
1730+
1731+
const getPk = (d: typeof data) => {
1732+
if (d == null) {
17421733
return null;
1743-
};
1744-
const upPk = getPk(data);
1745-
1746-
if (upPk) {
1747-
const { images } = formValues;
1748-
// res unit is saved, we can save changes to images
1749-
const success = await reconcileImageChanges(upPk, images);
1750-
if (success) {
1751-
// redirect if new one was created
1752-
if (formValues.pk === 0 && upPk > 0) {
1753-
history(`/unit/${unitPk}/reservationUnit/edit/${upPk}`);
1754-
}
1755-
const tkey =
1756-
formValues.pk === 0
1757-
? "ReservationUnitEditor.reservationUnitCreatedNotification"
1758-
: "ReservationUnitEditor.reservationUnitUpdatedNotification";
1759-
successToast({ text: t(tkey, { name: getValues("nameFi") }) });
1760-
} else {
1761-
errorToast({ text: "ReservationUnitEditor.imageSaveFailed" });
1762-
return undefined;
1763-
}
1764-
} else {
1765-
// eslint-disable-next-line no-console
1766-
console.warn(
1767-
"saved but, pk was not defined in mutation response: so images are not saved"
1768-
);
1769-
errorToast({ text: "ReservationUnitEditor.imageSaveFailed" });
1770-
return undefined;
17711734
}
1772-
refetch();
1773-
return upPk;
1774-
} catch (error) {
1775-
const validationErrors = getValidationErrors(error);
1776-
if (validationErrors.length > 0) {
1777-
const validationError = validationErrors[0];
1778-
errorToast({
1779-
text: t(`errors.backendValidation.${validationError.code}`),
1780-
});
1735+
if ("updateReservationUnit" in d) {
1736+
return d.updateReservationUnit?.pk ?? null;
1737+
}
1738+
if ("createReservationUnit" in d) {
1739+
return d.createReservationUnit?.pk ?? null;
1740+
}
1741+
return null;
1742+
};
1743+
const upPk = getPk(data);
1744+
1745+
// crude way to handle different logic for archive vs save (avoids double toast)
1746+
if (upPk && !formValues.isArchived) {
1747+
const { images } = formValues;
1748+
// res unit is saved, we can save changes to images
1749+
const success = await reconcileImageChanges(upPk, images);
1750+
if (success) {
1751+
// redirect if new one was created
1752+
if (formValues.pk === 0 && upPk > 0) {
1753+
history(getReservationUnitUrl(upPk, unitPk));
1754+
}
1755+
const tkey =
1756+
formValues.pk === 0
1757+
? "ReservationUnitEditor.reservationUnitCreatedNotification"
1758+
: "ReservationUnitEditor.reservationUnitUpdatedNotification";
1759+
successToast({ text: t(tkey, { name: getValues("nameFi") }) });
17811760
} else {
1782-
errorToast({ text: t("ReservationDialog.saveFailed") });
1761+
const msg = t("ReservationUnitEditor.imageSaveFailed");
1762+
throw new Error(msg);
17831763
}
1764+
} else if (upPk == null) {
1765+
const msg = t("ReservationUnitEditor.saveFailed", { error: "" });
1766+
throw new Error(msg);
1767+
}
1768+
refetch();
1769+
return upPk;
1770+
};
1771+
1772+
const handleError = (e: unknown) => {
1773+
const validationErrors = getValidationErrors(e);
1774+
if (validationErrors.length > 0) {
1775+
const validationError = validationErrors[0];
1776+
errorToast({
1777+
text: t(`errors.backendValidation.${validationError.code}`),
1778+
});
1779+
} else if (e instanceof Error) {
1780+
const msg = e.message;
1781+
errorToast({ text: msg });
1782+
} else {
1783+
errorToast({ text: t("ReservationDialog.saveFailed") });
17841784
}
1785-
return undefined;
17861785
};
17871786

17881787
// Have to define these like this because otherwise the state changes don't work
17891788
const handlePublish = async () => {
17901789
setValue("isDraft", false);
17911790
setValue("isArchived", false);
1792-
await handleSubmit(onSubmit)();
1791+
try {
1792+
await handleSubmit(onSubmit)();
1793+
} catch (error) {
1794+
handleError(error);
1795+
}
17931796
};
17941797

17951798
const handleSaveAsDraft = async () => {
17961799
setValue("isDraft", true);
17971800
setValue("isArchived", false);
1798-
await handleSubmit(onSubmit)();
1801+
try {
1802+
await handleSubmit(onSubmit)();
1803+
} catch (error) {
1804+
handleError(error);
1805+
}
17991806
};
18001807

18011808
const handleAcceptArchive = async () => {
18021809
setValue("isArchived", true);
18031810
setValue("isDraft", false);
1811+
setModalContent(null);
18041812
try {
18051813
await handleSubmit(onSubmit)();
1806-
setModalContent(null);
18071814
successToast({ text: t("ArchiveReservationUnitDialog.success") });
1808-
history(`/unit/${unit?.pk}`);
1815+
history(getUnitUrl(unit?.pk));
18091816
} catch (e) {
1810-
// eslint-disable-next-line no-console
1811-
console.warn("unable to archive", e);
1817+
handleError(e);
18121818
}
18131819
};
18141820

0 commit comments

Comments
 (0)