don't delete a gift image on an edit unless they hit 'save'

This commit is contained in:
2026-03-22 20:07:59 -06:00
parent ad8df3eb93
commit e9ad61b780
2 changed files with 24 additions and 35 deletions

View File

@@ -1175,11 +1175,6 @@ export const NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_CONFIRM = {
message: "", message: "",
}; };
export const NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_ERROR = {
title: "Error",
message: "There was a problem deleting the image.",
};
export const NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER = { export const NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER = {
title: "Missing Identifier", title: "Missing Identifier",
message: "You must select an identifier before you can record a give.", message: "You must select an identifier before you can record a give.",

View File

@@ -263,7 +263,6 @@ import { showSeedPhraseReminder } from "@/utils/seedPhraseReminder";
import { import {
NOTIFY_GIFTED_DETAILS_RETRIEVAL_ERROR, NOTIFY_GIFTED_DETAILS_RETRIEVAL_ERROR,
NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_CONFIRM, NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_CONFIRM,
NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_ERROR,
NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER, NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER,
NOTIFY_GIFT_ERROR_NEGATIVE_AMOUNT, NOTIFY_GIFT_ERROR_NEGATIVE_AMOUNT,
NOTIFY_GIFTED_DETAILS_RECORDING_GIVE, NOTIFY_GIFTED_DETAILS_RECORDING_GIVE,
@@ -302,6 +301,7 @@ export default class GiftedDetails extends Vue {
giverName = ""; giverName = "";
hideBackButton = false; hideBackButton = false;
imageUrl = ""; imageUrl = "";
imageUrlToDelete = "";
message = ""; message = "";
offerId = ""; offerId = "";
prevCredToEdit?: GenericCredWrapper<GiveActionClaim>; prevCredToEdit?: GenericCredWrapper<GiveActionClaim>;
@@ -517,9 +517,9 @@ export default class GiftedDetails extends Vue {
} }
cancel() { cancel() {
// Only delete if the image was freshly uploaded, not loaded from an existing claim // Only delete freshly uploaded images, not ones from an existing claim
if (this.imageUrl !== this.prevCredToEdit?.claim?.image) { if (this.imageUrl && this.imageUrl !== this.prevCredToEdit?.claim?.image) {
this.deleteImage(); // not awaiting, so they'll go back immediately this.deleteImage(this.imageUrl); // not awaiting, so they'll go back immediately
} }
if (this.destinationPathAfter) { if (this.destinationPathAfter) {
(this.$router as Router).push({ path: this.destinationPathAfter }); (this.$router as Router).push({ path: this.destinationPathAfter });
@@ -529,9 +529,9 @@ export default class GiftedDetails extends Vue {
} }
cancelBack() { cancelBack() {
// Only delete if the image was freshly uploaded, not loaded from an existing claim // Only delete freshly uploaded images, not ones from an existing claim
if (this.imageUrl !== this.prevCredToEdit?.claim?.image) { if (this.imageUrl && this.imageUrl !== this.prevCredToEdit?.claim?.image) {
this.deleteImage(); // not awaiting, so they'll go back immediately this.deleteImage(this.imageUrl); // not awaiting, so they'll go back immediately
} }
(this.$router as Router).back(); (this.$router as Router).back();
} }
@@ -545,13 +545,18 @@ export default class GiftedDetails extends Vue {
confirmDeleteImage() { confirmDeleteImage() {
this.notify.confirm( this.notify.confirm(
NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_CONFIRM.message, NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_CONFIRM.message,
this.deleteImage, () => {
// Stage the image for deletion on submit rather than deleting immediately,
// so that canceling the edit doesn't destroy the referenced image.
this.imageUrlToDelete = this.imageUrl;
this.imageUrl = "";
},
TIMEOUTS.LONG, TIMEOUTS.LONG,
); );
} }
async deleteImage() { async deleteImage(imageUrl: string) {
if (!this.imageUrl) { if (!imageUrl) {
return; return;
} }
try { try {
@@ -565,38 +570,21 @@ export default class GiftedDetails extends Vue {
); );
} }
const response = await this.axios.delete( const response = await this.axios.delete(
DEFAULT_IMAGE_API_SERVER + DEFAULT_IMAGE_API_SERVER + "/image/" + encodeURIComponent(imageUrl),
"/image/" +
encodeURIComponent(this.imageUrl),
{ headers }, { headers },
); );
if (response.status === 204) { if (response.status === 204) {
// don't bother with a notification // don't bother with a notification
// (either they'll simply continue or they're canceling and going back)
} else { } else {
logger.error("Problem deleting image:", response); logger.error("Problem deleting image:", response);
this.notify.error(
NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_ERROR.message,
TIMEOUTS.LONG,
);
return;
} }
this.imageUrl = "";
} catch (error) { } catch (error) {
logger.error("Error deleting image:", error); logger.error("Error deleting image:", error);
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((error as any)?.response?.status === 404) { if ((error as any)?.response?.status === 404) {
logger.log("Weird: the image was already deleted.", error); logger.log("Image was already deleted:", error);
this.imageUrl = "";
// it already doesn't exist so we won't say anything to the user
} else { } else {
this.notify.error( logger.error("Failed to delete image from server:", error);
NOTIFY_GIFTED_DETAILS_DELETE_IMAGE_ERROR.message,
TIMEOUTS.LONG,
);
} }
} }
} }
@@ -739,6 +727,12 @@ export default class GiftedDetails extends Vue {
TIMEOUTS.LONG, TIMEOUTS.LONG,
); );
} else { } else {
// Delete the old image from storage now that the edit is saved
if (this.imageUrlToDelete) {
this.deleteImage(this.imageUrlToDelete); // not awaiting
this.imageUrlToDelete = "";
}
this.notify.success( this.notify.success(
NOTIFY_GIFTED_DETAILS_GIFT_RECORDED.message, NOTIFY_GIFTED_DETAILS_GIFT_RECORDED.message,
TIMEOUTS.SHORT, TIMEOUTS.SHORT,