Skip to content

Aditya-feat: Add Network Failure Handling & Upload Status Feedback on Update Tool/Equipment Status Page#4999

Open
Aditya-gam wants to merge 4 commits intodevelopmentfrom
Aditya-feat/Add-Network-Failure-Handling-Upload-Status-Feedback-on-Update-Tool-Equipment-Status-Page
Open

Aditya-feat: Add Network Failure Handling & Upload Status Feedback on Update Tool/Equipment Status Page#4999
Aditya-gam wants to merge 4 commits intodevelopmentfrom
Aditya-feat/Add-Network-Failure-Handling-Upload-Status-Feedback-on-Update-Tool-Equipment-Status-Page

Conversation

@Aditya-gam
Copy link
Copy Markdown
Contributor

@Aditya-gam Aditya-gam commented Mar 15, 2026

Description

Adds image upload and upload-status feedback on the BM Dashboard Update Tool/Equipment Status page (/bmdashboard/tools/:equipmentId/update). The page previously only previewed images locally; this PR submits the selected image to the backend via the existing status-update API (multipart when an image is present), validates format (PNG/JPG/JPEG) and size (max 5 MB) before submit, and ensures every submission attempt results in clear success or failure feedback—including a user-friendly message when offline or when the image could not be saved (e.g. "No response from server. Please check your connection." and "Image selected but not saved."). The tools table is updated so the pencil icon links to the full update page instead of opening an update modal.
IssueDescription

Related PRs (if any):

  • Previous Frontend (merged): PR #4656
  • Backend status API (merged): PR #1984
  • Backend image upload (merged): PR #2103: Same endpoint now accepts an optional image via multipart/form-data (field image), validates PNG/JPEG/5 MB, stores in Azure, and persists imageUrl on equipment and update record.

Main changes explained:

Created/Updated Files:

  • src/actions/bmdashboard/equipmentActions.js (+26 / −3)
    • updateEquipment(equipmentId, updateData, imageFile = null) — Added optional third argument imageFile. When imageFile is provided, it builds a FormData with the same status fields (condition, createdBy, lastUsedBy, lastUsedFor, replacementRequired, description, notes) as form strings and appends the file under the field name image; it sends PUT with the FormData without setting Content-Type so axios sets multipart/form-data with the correct boundary. When imageFile is null/undefined, it keeps the existing behavior: sends JSON body via axios.put(url, statusUpdateData).
    • Optional fields in statusUpdateData are normalized with || '' for consistency when sent as form fields.
    • Error handling unchanged: uses err.response.data?.error then err.response.data?.message; for no response (err.request without err.response) uses "No response from server. Please check your connection."; toasts error and rethrows.
  • src/components/BMDashboard/Equipment/Update/UpdateEquipment.jsx (+66 / −33)
    • Constants: ALLOWED_MIME_TYPES = ['image/png', 'image/jpeg'], MAX_IMAGE_SIZE_BYTES = 5 * 1024 * 1024, INVALID_IMAGE_MSG = 'Invalid image. Use PNG, JPG, or JPEG under 5MB.' (aligned with backend message).
    • handleFileUpload: Restricts accepted files to PNG/JPEG (by MIME and extension \.(jpg|jpeg|png)$/i) and max 5 MB. When no valid files remain after filter, sets setSubmitError(INVALID_IMAGE_MSG) instead of console.warn.
    • handleSubmit: Before calling the action, when the user has selected files, validates the first file (type and size); if invalid, sets setSubmitError(INVALID_IMAGE_MSG) and returns without submitting. Passes uploadedFiles[0] ?? null as the third argument to updateEquipment. On success, shows "Equipment status updated successfully! Image saved." when an image was sent, otherwise "Equipment status updated successfully!"; always clears file preview state. On failure, builds error message from error.response?.data?.error (or message, or network message "No response from server. Please check your connection."); when images were selected, appends " Note: Images were selected and previewed but not saved to database." and marks previews as status: 'not-saved'. Ensures setIsSubmitting(false) in finally so no silent failures.
    • Labels/copy: "Accepted: PNG, JPG, JPEG (max 5MB)" and "Images will be submitted with the form and saved to the database." (replacing GIF/WEBP and "preview only" wording).
  • src/components/common/DragAndDrop/DragAndDrop.jsx (+2 / −2)
    • accept attribute changed from image/jpeg, image/jpg, image/png, image/gif, image/webp to image/png, image/jpeg, image/jpg to match backend.
    • Helper text updated from "Accepted: PNG, JPG, JPEG, GIF, WEBP" to "Accepted: PNG, JPG, JPEG (max 5MB)".
  • src/components/BMDashboard/ToolItemList/ToolItemsTable.jsx (+6 / −16)
    • Replaced the pencil button that opened UpdateItemModal with a Link to /bmdashboard/tools/${el._id}/update so users go to the full Update Tool/Equipment Status page. Removed UpdateItemModal prop and related state (updateModal, updateRecord) and handler handleEditRecordsClick. Added Link import from react-router-dom. The "View" button for updating records remains and still opens the records modal.

Key Implementation Details:

  • API contract: Endpoint remains PUT /api/bm/equipment/:equipmentId/status (see ENDPOINTS.BM_EQUIPMENT_STATUS_UPDATE(equipmentId) in src/utils/URL.js). With image: request is multipart/form-data with form fields plus one file under field name image; without image: request is application/json as before. Backend (PR fixed the edit time off request validation #2103) validates image type (PNG/JPEG) and size (5 MB) and returns response.data.error for validation/upload failures.
  • No Content-Type for FormData: When sending FormData, the code does not set Content-Type so the browser/axios can set multipart/form-data with the correct boundary, per backend contract.
  • Single image: Only the first selected file is sent (uploadedFiles[0]); backend accepts one file per request.
  • Error surface: User-facing messages come from err.response.data.error (then message); network/offline case uses the fixed string "No response from server. Please check your connection." so offline submission always shows a clear toast and in-page error.
  • Backward compatibility: When no image is selected, behavior is unchanged (JSON PUT). Parent of ToolItemsTable (ToolItemListView) still passes UpdateItemModal; the prop is simply no longer used by ToolItemsTable, so no parent change is required.

How to test:

  1. Check into current branch: Aditya-feat/Add-Network–Failure-Handling-Upload-Status-Feedback-on-Update-Tool-Equipment-Status-Page
  2. Ensure backend with image upload is running (e.g., HGNRest with PR fixed the edit time off request validation #2103 or equivalent) and Azure credentials are set in the backend .env file.
  3. Reinstall dependencies and clear cache: rm -rf node_modules && yarn cache clean
  4. Run yarn install and start the app: yarn start:local
  5. Login using Admin/Owner Login.
  6. Test Update Tool/Equipment Status with image:
    • Navigate directly to /bmdashboard/tools/:equipmentId/update with a valid equipment ID from GET /api/bm/equipments. I used these two for testing: 6680a2ec7e038e1028825dde, 6869da54b653924ff05eb471
    • Fill required fields (Status/Condition, Who used last, What used for, Replacement required). Optionally add an image via drag-and-drop or file picker (PNG or JPEG, < 5 MB).
    • Submit. Expect success toast and in-page message "Equipment status updated successfully! Image saved." when an image was included; the equipment detail/update page should show the new image (e.g., equipmentDetails.imageUrl).
  7. Test without image: Submit with no image selected. Expect "Equipment status updated successfully!" and no image in the request (JSON path).
  8. Test validation: Select a file that is not PNG/JPEG (e.g., GIF) or > 5 MB. Expect an inline error "Invalid image. Use PNG, JPG, or JPEG under 5MB." before or on submit.
  9. Test offline/failure: With an image selected, disconnect the network (or stop the backend) and submit. Expect toast and in-page error, including "No response from server. Please check your connection," and, when images were selected, "Note: Images were selected and previewed but not saved to database."
  10. Test tools table link: From the BM Dashboard → Tools list, click the pencil icon on a tool/equipment row. Expect navigation to /bmdashboard/tools/:id/update (full update page) instead of opening a modal.
  11. Verify: No silent failures—every submit shows either success or failure feedback (toast and in-page Alert). Backend 400/404/500/503 messages (e.g., "Image selected but not saved.", "Invalid image. Use PNG, JPG, or JPEG under 5MB.") appear as provided in response.data.error.

Screenshots or videos of changes:

  • Screenshot of Update Tool/Equipment Status page with image selected:
ImageSelectedLightMode ImageSelectedDarkMode
  • Test Video:
TestVideo.mov

Note:

  • Validation: Client-side: PNG/JPEG/JPG only, max 5 MB (aligned with backend). Backend re-validates and returns 400 with Invalid image. Use PNG, JPG, or JPEG under 5MB. when invalid.
  • Ensure backend is running with the image-upload implementation (e.g., PR fixed the edit time off request validation #2103) for full image save and imageUrl in response.
  • In my testing video, uploading the image throws an error. That is because I don't have the Azure environment variables for the backend. The rest of the functionality works, and once I get the variables, I will update the test videos.

Add optional image param to updateEquipment; when present send multipart/form-data with field 'image' and do not set Content-Type. Restrict accepted formats to PNG/JPEG and 5MB in UpdateEquipment and DragAndDrop. Validate before submit and surface backend error message; clear file state on success and append note when image not saved on failure.

Made-with: Cursor
Replace edit-button modal with Link to /bmdashboard/tools/:id/update so users open the full update page. Remove UpdateItemModal prop and related state from ToolItemsTable.

Made-with: Cursor
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 15, 2026

Deploy Preview for highestgoodnetwork-dev ready!

Name Link
🔨 Latest commit c750792
🔍 Latest deploy log https://app.netlify.com/projects/highestgoodnetwork-dev/deploys/69b604cd9f3b2f0008628afc
😎 Deploy Preview https://deploy-preview-4999--highestgoodnetwork-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Replace pencil button that opened UpdatesEdit modal with Link to /bmdashboard/tools/:id/update so users open the full Update Tool/Equipment Status page from the equipment list table.

Made-with: Cursor
Revert pencil from Link to update page back to button that opens UpdateItemModal. Restore UpdateItemModal prop and related state (updateModal, updateRecord) and handleEditRecordsClick.

Made-with: Cursor
@sonarqubecloud
Copy link
Copy Markdown

@one-community one-community added the High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants