Skip to content

feat: add drag-and-drop logo upload for organizations - #4765

Merged
narcisonunez merged 14 commits into
Dokploy:canaryfrom
imrja8:feat/organization-logo-drag-drop
Sep 3, 2026
Merged

narcisonunez merged 14 commits into
Dokploy:canaryfrom
imrja8:feat/organization-logo-drag-drop

Conversation

@imrja8

@imrja8 imrja8 commented Jul 8, 2026 •

Copy link
Copy Markdown
Collaborator

What is this PR about?

This PR introduces a drag-and-drop feature for uploading Organization Profiles/Logos. It brings parity to how icons are managed elsewhere in the application, but with a heavy emphasis on security, performance, and user experience.

User Experience (UX)

  • Drag-and-Drop Integration: Integrated the Dropzone component into the "Add/Update Organization" dialog for seamless file uploads.
  • Intelligent Input Masking: Instead of cluttering the "Logo URL" input with a massive Base64 string upon upload, the input gracefully masks it by displaying the uploaded filename (e.g., logo.png) or a fallback "Uploaded image" text.
  • Instant Preview & Layout Stability: Added a fixed-size thumbnail preview next to the input field. It defaults to a GlobeIcon and instantly swaps to the uploaded image without causing jarring layout shifts.
  • Dialog Stability Fix: Resolved a native UI conflict where clicking the file picker inside a nested DropdownMenu caused the dialog to prematurely close. Fixed by decoupling the AddOrganization dialog from the dropdown trigger.

Security

  • SVG Sanitization: All .svg uploads are parsed through DOMPurify to strip arbitrary <script> tags and mitigate XSS risks.
  • Unicode Base64 Safety: The sanitized SVG is converted to a byte array using TextEncoder before btoa encoding, completely preventing browser crashes when an SVG contains Unicode characters or emojis.
  • Race Condition Prevention: Implemented a robust useRef invalidation system. If a user manually edits the URL, clears the input, or closes the dialog while a background upload is processing, the pending background task is instantly aborted and guaranteed not to overwrite the form state.

Performance

  • Client-Side Compression: To prevent severe database bloat on the organization table, any raster images (JPG, PNG) uploaded via the dropzone are instantly processed through a background HTML Canvas, resized to a maximum of 256x256 pixels, and compressed into the highly efficient WebP format. This shrinks typical 2MB user uploads to roughly ~15KB before they ever hit the database.

Why and How

Users requested the ability to easily upload organization logos. However, storing raw, massive Base64 images directly into the PostgreSQL TEXT column creates unnecessary network/DB bottlenecks. Utilized FileReader to extract file contents, DOMPurify for SVG cleaning, and a native canvas context for downscaling raster images. Furthermore, the global Dropzone UI component was updated with a new classNameContent prop to allow targeted height overrides, ensuring this specific dropzone fits the form perfectly without affecting global instances.

Verification

  • Tested manually in the browser.
  • Verified dialog stability (no auto-close on file picker focus loss).
  • Confirmed SVG sanitization strips arbitrary tags.
  • Verified client-side compression drastically shrinks the Base64 payload prior to form submission.
  • Checked local formatting and changes.

Checklist

Before submitting this PR, please make sure that:

Issues related (if applicable)

closes #4727

Screenshots (if applicable)

  • Custom URL Input Working Perfectly
    Screenshot 2026-07-08 at 10 11 31

  • Drag and Drop Working Perfectly
    Screenshot 2026-07-08 at 10 14 29

Greptile Summary

The PR adds drag-and-drop organization logo uploads with SVG sanitization, raster resizing, previews, and lifecycle safeguards.

  • Supports JPEG, PNG, WebP, and sanitized SVG uploads.
  • Resizes raster images to a maximum of 256×256 and stores them as WebP data URLs.
  • Prevents stale upload completion after replacement, editing, clearing, or dialog closure.
  • Adds configurable Dropzone content sizing for the organization form.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Reviews (6): Last reviewed commit: "Merge branch 'Dokploy:canary' into feat/..." | Re-trigger Greptile

- Integrated Dropzone component into handle-organization.tsx.
- Resolved dialog auto-close bug by decoupling Dialog from DropdownMenu trigger.
- Added DOMPurify to sanitize uploaded SVG logos preventing XSS.
- Implemented client-side compression via canvas to resize raster images to 256x256 WebP.
- Enhanced UX with instant logo preview, masked base64 input strings, and a quick-clear button.
- Updated Dropzone to accept classNameContent for local height overrides.
@imrja8
imrja8 requested a review from Siumauricio as a code owner July 8, 2026 05:00
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Jul 8, 2026
@imrja8
imrja8 marked this pull request as draft September 1, 2026 19:37
@imrja8
imrja8 marked this pull request as ready for review September 1, 2026 19:37
@imrja8
imrja8 force-pushed the feat/organization-logo-drag-drop branch from 898e914 to 6d51c10 Compare September 1, 2026 20:25
@imrja8
imrja8 marked this pull request as draft September 1, 2026 20:31
@imrja8
imrja8 marked this pull request as ready for review September 1, 2026 20:31
@imrja8
imrja8 force-pushed the feat/organization-logo-drag-drop branch from efa904c to 0af50cb Compare September 1, 2026 20:39
@imrja8
imrja8 marked this pull request as draft September 1, 2026 20:40
@imrja8
imrja8 marked this pull request as ready for review September 1, 2026 20:40
@imrja8
imrja8 force-pushed the feat/organization-logo-drag-drop branch from 0af50cb to c1af9d4 Compare September 1, 2026 20:48
@imrja8
imrja8 marked this pull request as draft September 1, 2026 20:50
@imrja8
imrja8 marked this pull request as ready for review September 1, 2026 20:50
@imrja8
imrja8 marked this pull request as draft September 1, 2026 20:54
@imrja8
imrja8 force-pushed the feat/organization-logo-drag-drop branch from c1af9d4 to 93b0909 Compare September 1, 2026 20:55
@imrja8
imrja8 force-pushed the feat/organization-logo-drag-drop branch from 9b0aa0e to 8806d4e Compare September 1, 2026 20:57
@imrja8
imrja8 marked this pull request as ready for review September 1, 2026 20:59
@imrja8
imrja8 marked this pull request as draft September 2, 2026 08:58
@imrja8
imrja8 marked this pull request as ready for review September 2, 2026 12:00
@imrja8
imrja8 force-pushed the feat/organization-logo-drag-drop branch from d08796e to 4877c4f Compare September 2, 2026 15:19
@imrja8
imrja8 requested a review from narcisonunez September 2, 2026 15:27
@narcisonunez

Copy link
Copy Markdown
Collaborator

LGTM! I will complete the approval process later

@narcisonunez
narcisonunez merged commit f4e1154 into Dokploy:canary Sep 3, 2026
4 checks passed
@imrja8
imrja8 deleted the feat/organization-logo-drag-drop branch September 4, 2026 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Organization Profile Upload

2 participants