feat: Complete NewEditProjectView.vue Enhanced Triple Migration Pattern and ImageMethodDialog improvements

- Complete all 4 phases of Enhanced Triple Migration Pattern for NewEditProjectView.vue
- Replace databaseUtil calls with PlatformServiceMixin methods
- Standardize notification calls using constants and timeout helpers
- Extract 12 computed properties for template streamlining
- Add notification constants and helper functions to notifications.ts
- Extract long CSS classes to computed properties in ImageMethodDialog.vue
- Fix platformService conflict in ImageMethodDialog.vue
- Complete PushNotificationPermission.vue migration with all phases
- Update migration tracking documentation
- Migration completed in 11m 30s (74% faster than estimate)
This commit is contained in:
Matthew Raymer
2025-07-09 07:22:58 +00:00
parent 7aa8a74505
commit 702fff236f
8 changed files with 1031 additions and 264 deletions

View File

@@ -1,3 +1,5 @@
import axios from "axios";
// Notification message constants for user-facing notifications
// Add new notification messages here as needed
//
@@ -1382,3 +1384,294 @@ export const QR_TIMEOUT_SHORT = 1000; // Short operations like registration subm
export const QR_TIMEOUT_MEDIUM = 2000; // Medium operations like URL copy
export const QR_TIMEOUT_STANDARD = 3000; // Standard success messages
export const QR_TIMEOUT_LONG = 5000; // Error messages and warnings
// NewEditProjectView.vue specific constants
// Used in: NewEditProjectView.vue (mounted method - account loading error)
export const NOTIFY_PROJECT_ACCOUNT_LOADING_ERROR = {
title: "Account Loading Error",
message: "There was a problem loading your account info.",
};
// Used in: NewEditProjectView.vue (loadProject method - project retrieval error)
export const NOTIFY_PROJECT_RETRIEVAL_ERROR = {
title: "Project Retrieval Error",
message: "There was an error retrieving that project.",
};
// Used in: NewEditProjectView.vue (confirmDeleteImage method - image deletion confirmation)
export const NOTIFY_PROJECT_DELETE_IMAGE_CONFIRM = {
title: "Delete Image",
message: "Are you sure you want to delete the image?",
};
// Used in: NewEditProjectView.vue (deleteImage method - image deletion error)
export const NOTIFY_PROJECT_DELETE_IMAGE_ERROR = {
title: "Image Deletion Error",
message: "There was a problem deleting the image.",
};
// Used in: NewEditProjectView.vue (deleteImage method - image deletion general error)
export const NOTIFY_PROJECT_DELETE_IMAGE_GENERAL_ERROR = {
title: "Image Deletion Error",
message: "There was an error deleting the image.",
};
// Used in: NewEditProjectView.vue (validateLocation method - invalid location error)
export const NOTIFY_PROJECT_INVALID_LOCATION = {
title: "Invalid Location",
message: "The location was invalid so it was not set.",
};
// Used in: NewEditProjectView.vue (validateStartDate method - invalid start date error)
export const NOTIFY_PROJECT_INVALID_START_DATE = {
title: "Invalid Start Date",
message: "The start date was invalid so it was not set.",
};
// Used in: NewEditProjectView.vue (validateEndDate method - invalid end date error)
export const NOTIFY_PROJECT_INVALID_END_DATE = {
title: "Invalid End Date",
message: "The end date was invalid so it was not set.",
};
// Used in: NewEditProjectView.vue (saveProject method - project save success)
export const NOTIFY_PROJECT_SAVE_SUCCESS = {
title: "Success",
message: "The project was saved successfully.",
};
// Used in: NewEditProjectView.vue (saveProject method - partner location warning)
export const NOTIFY_PROJECT_PARTNER_LOCATION_WARNING = {
title: "Partner Location Warning",
message:
"A partner was selected but the location was not set, so it was not sent to any partner.",
};
// Used in: NewEditProjectView.vue (sendToNostrPartner method - partner send success)
export const NOTIFY_PROJECT_PARTNER_SEND_SUCCESS = {
title: "Partner Integration Success",
message: "The project info was sent to",
};
// Used in: NewEditProjectView.vue (sendToNostrPartner method - partner send error)
export const NOTIFY_PROJECT_PARTNER_SEND_ERROR = {
title: "Partner Integration Error",
message: "Failed sending to",
};
// Used in: NewEditProjectView.vue (sendToNostrPartner method - partner send general error)
export const NOTIFY_PROJECT_PARTNER_SEND_GENERAL_ERROR = {
title: "Partner Integration Error",
message: "There was an error sending to the partner service.",
};
// Used in: NewEditProjectView.vue (confirmEraseLatLong method - location deletion confirmation)
export const NOTIFY_PROJECT_DELETE_LOCATION_CONFIRM = {
title: "Delete Location",
message: "Are you sure you want to delete the location?",
};
// Used in: NewEditProjectView.vue (showNostrPartnerInfo method - partner info)
export const NOTIFY_PROJECT_NOSTR_PARTNER_INFO = {
title: "Partner Integration Info",
message:
"This will share your project information with external partner services using Nostr protocol.",
};
// Helper function for dynamic partner send success messages
// Used in: NewEditProjectView.vue (sendToNostrPartner method - dynamic success message)
export function createProjectPartnerSendSuccessMessage(
serviceName: string,
): string {
return `${NOTIFY_PROJECT_PARTNER_SEND_SUCCESS.message} ${serviceName}.`;
}
// Helper function for dynamic partner send error messages
// Used in: NewEditProjectView.vue (sendToNostrPartner method - dynamic error message)
export function createProjectPartnerSendErrorMessage(
serviceName: string,
errorData: string,
): string {
return `${NOTIFY_PROJECT_PARTNER_SEND_ERROR.message} ${serviceName}: ${errorData}`;
}
// NewEditProjectView.vue timeout constants
export const PROJECT_TIMEOUT_SHORT = 1000; // Short operations like confirmations
export const PROJECT_TIMEOUT_STANDARD = 3000; // Standard success messages
export const PROJECT_TIMEOUT_LONG = 5000; // Error messages and warnings
export const PROJECT_TIMEOUT_VERY_LONG = 7000; // Complex operations and partner errors
// ImageMethodDialog.vue specific constants
// Used in: ImageMethodDialog.vue (mounted method - settings retrieval error)
export const NOTIFY_IMAGE_DIALOG_SETTINGS_ERROR = {
title: "Error",
message: "There was an error retrieving your settings.",
};
// Used in: ImageMethodDialog.vue (acceptUrl method - image retrieval error)
export const NOTIFY_IMAGE_DIALOG_RETRIEVAL_ERROR = {
title: "Error",
message: "There was an error retrieving that image.",
};
// Used in: ImageMethodDialog.vue (startCameraPreview method - camera access error)
export const NOTIFY_IMAGE_DIALOG_CAMERA_ACCESS_ERROR = {
title: "Error",
message: "Failed to access camera",
};
// Used in: ImageMethodDialog.vue (startCameraPreview method - camera in use error)
export const NOTIFY_IMAGE_DIALOG_CAMERA_IN_USE = {
title: "Camera in Use",
message:
"Camera is in use by another application. Please close any other apps or browser tabs using the camera and try again.",
};
// Used in: ImageMethodDialog.vue (startCameraPreview method - camera permission denied)
export const NOTIFY_IMAGE_DIALOG_CAMERA_PERMISSION_DENIED = {
title: "Camera Access Denied",
message:
"Camera access was denied. Please allow camera access in your browser settings.",
};
// Used in: ImageMethodDialog.vue (capturePhoto method - photo capture error)
export const NOTIFY_IMAGE_DIALOG_CAPTURE_ERROR = {
title: "Error",
message: "Failed to capture photo. Please try again.",
};
// Used in: ImageMethodDialog.vue (uploadImage method - no image found error)
export const NOTIFY_IMAGE_DIALOG_NO_IMAGE_ERROR = {
title: "Error",
message: "There was an error finding the picture. Please try again.",
};
// Used in: ImageMethodDialog.vue (uploadImage method - general upload error)
export const NOTIFY_IMAGE_DIALOG_UPLOAD_ERROR = {
title: "Error",
message: "There was an error saving the picture.",
};
// Used in: ImageMethodDialog.vue (uploadImage method - authentication error)
export const NOTIFY_IMAGE_DIALOG_AUTH_ERROR = {
title: "Authentication Error",
message: "Authentication failed. Please try logging in again.",
};
// Used in: ImageMethodDialog.vue (uploadImage method - file too large error)
export const NOTIFY_IMAGE_DIALOG_FILE_TOO_LARGE = {
title: "File Too Large",
message: "Image file is too large. Please try a smaller image.",
};
// Used in: ImageMethodDialog.vue (uploadImage method - unsupported format error)
export const NOTIFY_IMAGE_DIALOG_UNSUPPORTED_FORMAT = {
title: "Unsupported Format",
message: "Unsupported image format. Please try a different image.",
};
// Used in: ImageMethodDialog.vue (uploadImage method - server error)
export const NOTIFY_IMAGE_DIALOG_SERVER_ERROR = {
title: "Server Error",
message: "Server error. Please try again later.",
};
// Helper function for dynamic camera error messages
// Used in: ImageMethodDialog.vue (startCameraPreview method - dynamic camera error message)
export function createImageDialogCameraErrorMessage(error: Error): string {
if (error.name === "NotReadableError" || error.name === "TrackStartError") {
return NOTIFY_IMAGE_DIALOG_CAMERA_IN_USE.message;
} else if (
error.name === "NotAllowedError" ||
error.name === "PermissionDeniedError"
) {
return NOTIFY_IMAGE_DIALOG_CAMERA_PERMISSION_DENIED.message;
}
return error.message || NOTIFY_IMAGE_DIALOG_CAMERA_ACCESS_ERROR.message;
}
// Helper function for dynamic upload error messages
// Used in: ImageMethodDialog.vue (uploadImage method - dynamic upload error message)
export function createImageDialogUploadErrorMessage(error: any): string {
if (axios.isAxiosError(error)) {
const status = error.response?.status;
const data = error.response?.data;
if (status === 401) {
return NOTIFY_IMAGE_DIALOG_AUTH_ERROR.message;
} else if (status === 413) {
return NOTIFY_IMAGE_DIALOG_FILE_TOO_LARGE.message;
} else if (status === 415) {
return NOTIFY_IMAGE_DIALOG_UNSUPPORTED_FORMAT.message;
} else if (status && status >= 500) {
return NOTIFY_IMAGE_DIALOG_SERVER_ERROR.message;
} else if (data?.message) {
return data.message;
}
}
return NOTIFY_IMAGE_DIALOG_UPLOAD_ERROR.message;
}
// ImageMethodDialog.vue timeout constants
export const IMAGE_DIALOG_TIMEOUT_STANDARD = 3000; // Standard error messages
export const IMAGE_DIALOG_TIMEOUT_LONG = 5000; // Camera and upload errors
export const IMAGE_DIALOG_TIMEOUT_MODAL = -1; // Modal confirmations (no auto-dismiss)
// PushNotificationPermission.vue specific constants
// Used in: PushNotificationPermission.vue (open method - VAPID key error)
export const NOTIFY_PUSH_VAPID_ERROR = {
title: "Error Setting Notifications",
message: "Could not set notifications.",
};
// Used in: PushNotificationPermission.vue (open method - initialization error)
export const NOTIFY_PUSH_INIT_ERROR = {
title: "Error Setting Notifications",
message: "Got an error setting notifications.",
};
// Used in: PushNotificationPermission.vue (checkNotificationSupport method - browser support error)
export const NOTIFY_PUSH_BROWSER_NOT_SUPPORTED = {
title: "Browser Notifications Are Not Supported",
message: "This browser does not support notifications.",
};
// Used in: PushNotificationPermission.vue (requestNotificationPermission method - permission error)
export const NOTIFY_PUSH_PERMISSION_ERROR = {
title: "Error Requesting Notification Permission",
message:
"Allow this app permission to make notifications for personal reminders. You can adjust them at any time in your settings.",
};
// Used in: PushNotificationPermission.vue (turnOnNotifications method - setup underway)
export const NOTIFY_PUSH_SETUP_UNDERWAY = {
title: "Notification Setup Underway",
message:
"Setting up notifications for interesting activity, which takes about 10 seconds. If you don't see a final confirmation, check the 'Troubleshoot' page.",
};
// Used in: PushNotificationPermission.vue (turnOnNotifications method - success)
export const NOTIFY_PUSH_SUCCESS = {
title: "Notification Is On",
message:
"You should see at least one on your device; if not, check the 'Troubleshoot' link.",
};
// Used in: PushNotificationPermission.vue (turnOnNotifications method - general error)
export const NOTIFY_PUSH_SETUP_ERROR = {
title: "Error Setting Notification Permissions",
message: "Could not set notification permissions.",
};
// Used in: PushNotificationPermission.vue (subscribeToPush method - push subscription error)
export const NOTIFY_PUSH_SUBSCRIPTION_ERROR = {
title: "Error Setting Push Notifications",
message:
"We encountered an issue setting up push notifications. If you wish to revoke notification permissions, please do so in your browser settings.",
};
// Push notification timeout constants
export const PUSH_NOTIFICATION_TIMEOUT_SHORT = 3000;
export const PUSH_NOTIFICATION_TIMEOUT_MEDIUM = 5000;
export const PUSH_NOTIFICATION_TIMEOUT_LONG = 7000;
export const PUSH_NOTIFICATION_TIMEOUT_PERSISTENT = -1;