Skip to content

CSV Uploads#2134

Open
GelatoGenesis wants to merge 2 commits intomainfrom
b-17737554273
Open

CSV Uploads#2134
GelatoGenesis wants to merge 2 commits intomainfrom
b-17737554273

Conversation

@GelatoGenesis
Copy link
Copy Markdown
Collaborator

@GelatoGenesis GelatoGenesis commented Mar 17, 2026

Summary by CodeRabbit

  • New Features

    • Added CSV file upload support in chat mode
    • CSV attachments now display as downloadable items with proper icons and labels
  • Tests

    • Added comprehensive test coverage for CSV file upload and display functionality across multiple components and services

Signed-off-by: GelatoGenesis <tarmokalling@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0b2ed933-507b-4365-ac42-6f1d88e8c72d

📥 Commits

Reviewing files that changed from the base of the PR and between cf473a4 and 010b2c3.

📒 Files selected for processing (1)
  • __tests__/components/drops/create/utils/CreateDropActionsRow.test.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/components/drops/create/utils/CreateDropActionsRow.test.tsx

📝 Walkthrough

Walkthrough

The PR introduces comprehensive CSV file support to the drop/wave upload system. Changes include new file type detection for CSV files, conditional CSV acceptance based on upload mode (chat mode allows CSV, drop mode rejects it), a new DropMediaAttachmentCard component for CSV rendering, MIME type normalization for CSV files, and corresponding test coverage across multiple components.

Changes

Cohort / File(s) Summary
Test Coverage for CSV Support
__tests__/components/drops/create/utils/CreateDropActionsRow.test.tsx, __tests__/components/drops/view/item/content/media/DropListItemContentMedia.test.tsx, __tests__/components/drops/view/item/content/media/MediaDisplay.test.tsx, __tests__/components/waves/CreateDropActions.test.tsx, __tests__/services/uploads/multipartUploadCore.test.ts
Adds tests verifying CSV file handling: dynamic error messages using MAX_DROP_UPLOAD_FILES, CSV file rendering in media components, conditional CSV acceptance based on drop mode, and MIME type normalization for CSV files.
File Type Detection & Selection
components/drops/create/utils/file/CreateDropSelectedFileIcon.tsx, components/drops/create/utils/file/CreateDropSelectedFilePreview.tsx
Adds FILE_TYPES.CSV enum member and detection logic (by MIME type or .csv extension) to render CSV icons and attachment cards in file preview.
CSV Media Rendering
components/drops/view/item/content/media/DropMediaAttachmentCard.tsx, components/drops/view/item/content/media/DropListItemContentMedia.tsx, components/drops/view/item/content/media/MediaDisplay.tsx
New DropMediaAttachmentCard component for rendering CSV attachments; extends DropListItemContentMedia and MediaDisplay to recognize text/csv MIME type and render CSV content via the attachment card.
Upload Mode Control
components/waves/CreateDropActions.tsx, components/waves/CreateDropContent.tsx
CreateDropActions conditionally accepts CSV files in chat mode only (fileInputAccept varies by isDropMode); CreateDropContent filters and rejects CSV files during drop mode with error toast.
MIME Type Normalization
services/uploads/multipartUploadCore.ts
Extends getContentType to prioritize CSV detection by filename and normalize CSV MIME types to text/csv before other checks.

Sequence Diagram

sequenceDiagram
    actor User
    participant CreateDropActions as CreateDropActions<br/>(Chat/Drop Mode)
    participant CreateDropContent as CreateDropContent<br/>(File Handler)
    participant multipartUploadCore as multipartUploadCore<br/>(MIME Normalization)
    participant MediaDisplay as MediaDisplay<br/>(CSV Rendering)
    participant DropMediaAttachmentCard as DropMediaAttachmentCard

    User->>CreateDropActions: Selects file
    alt Chat Mode (isDropMode=false)
        CreateDropActions->>CreateDropActions: fileInputAccept includes .csv, text/csv
        CreateDropActions->>User: Allows CSV selection
    else Drop Mode (isDropMode=true)
        CreateDropActions->>CreateDropActions: fileInputAccept excludes .csv
        CreateDropActions->>User: Rejects CSV selection
    end

    alt File Upload in Drop Mode
        User->>CreateDropContent: Uploads file
        CreateDropContent->>CreateDropContent: Check isCsvFile()
        alt Is CSV
            CreateDropContent->>User: Show error toast, reject
        else Not CSV
            CreateDropContent->>multipartUploadCore: Upload file
            multipartUploadCore->>multipartUploadCore: Normalize MIME to text/csv if CSV
            multipartUploadCore->>CreateDropContent: Return with normalized type
        end
    end

    CreateDropContent->>MediaDisplay: Display file
    alt Media MIME Type is text/csv
        MediaDisplay->>DropMediaAttachmentCard: Render CSV attachment
        DropMediaAttachmentCard->>User: Show CSV icon + download
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • ragnep
  • prxt6529
  • simo6529

Poem

🐰 A CSV bounces through the waves,
In chat mode, welcome it behaves!
But drops reject with careful grace,
While attachment cards show its face. ✨📎

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'CSV Uploads' is concise and directly summarizes the main change—adding CSV file upload support throughout the codebase. It clearly reflects the primary objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch b-17737554273
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
components/drops/view/item/content/media/MediaDisplay.tsx (1)

11-19: Consider consolidating MediaType enum and getMediaType logic.

The MediaType enum and getMediaType function are duplicated between this file and DropListItemContentMedia.tsx. While the current implementation is correct, this duplication could lead to inconsistencies if future media types are added to one file but not the other.

♻️ Suggested approach

Extract to a shared utility:

// e.g., helpers/mediaType.helpers.ts
export enum MediaType {
  IMAGE = "IMAGE",
  VIDEO = "VIDEO",
  AUDIO = "AUDIO",
  GLB = "GLB",
  HTML = "HTML",
  CSV = "CSV",
  UNKNOWN = "UNKNOWN",
}

export const getMediaType = (
  mimeType: string,
  url: string
): MediaType => {
  // ... shared detection logic
};

Both MediaDisplay.tsx and DropListItemContentMedia.tsx can then import and use this shared utility.

Also applies to: 47-72

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/drops/view/item/content/media/MediaDisplay.tsx` around lines 11 -
19, The MediaType enum and getMediaType detection logic are duplicated between
MediaDisplay.tsx and DropListItemContentMedia.tsx; extract both into a shared
helper (e.g., helpers/mediaType.helpers.ts) exporting the MediaType enum and
getMediaType function, update MediaDisplay.tsx to import MediaType and
getMediaType (references: MediaType, getMediaType) and remove the local
enum/function, and update DropListItemContentMedia.tsx to import the same shared
symbols so both components use the single source of truth for media type
detection.
components/drops/create/utils/file/CreateDropSelectedFilePreview.tsx (1)

15-29: Consider extracting shared getFileType logic to reduce duplication.

This getFileType function is nearly identical to the one in CreateDropSelectedFileIcon.tsx (see context snippet 1), with the only difference being the return value for unknown types (FILE_TYPES.UNKNOWN vs null). Having two separate implementations increases the risk of them diverging when new file types are added.

♻️ Proposed consolidation approach

Create a shared utility:

// e.g., in helpers/file.helpers.ts or a new file
export const detectFileType = (file: File | null): FILE_TYPES | null => {
  if (!file) return null;
  if (file.type.includes("image")) return FILE_TYPES.IMAGE;
  if (file.type.includes("video")) return FILE_TYPES.VIDEO;
  if (file.type.includes("audio")) return FILE_TYPES.AUDIO;
  if (file.type === "text/csv" || file.name.toLowerCase().endsWith(".csv")) {
    return FILE_TYPES.CSV;
  }
  return null;
};

Then each consumer can handle the null case as needed (returning UNKNOWN or keeping null).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/drops/create/utils/file/CreateDropSelectedFilePreview.tsx` around
lines 15 - 29, The getFileType implementation in
CreateDropSelectedFilePreview.tsx duplicates logic found in
CreateDropSelectedFileIcon.tsx; extract that logic into a single exported helper
(e.g., detectFileType in a new helpers/file.helpers.ts) that accepts File | null
and returns FILE_TYPES | null, update both components to import and call
detectFileType, and in CreateDropSelectedFilePreview.tsx map a null result to
FILE_TYPES.UNKNOWN (while the other consumer can keep null) and remove the local
getFileType implementation so the shared helper is the single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/drops/create/utils/CreateDropActionsRow.tsx`:
- Line 46: The accept attribute in CreateDropActionsRow currently
unconditionally includes ".csv,text/csv", which bypasses the drop-mode
restriction; modify CreateDropActionsRow to conditionally omit CSV MIME/types
when in drop mode by mirroring the mode gating used in CreateDropActions (use
the same mode prop or isDropMode flag passed from CreateDropActions), build the
accept string dynamically (exclude ".csv" and "text/csv" when mode === 'drop' or
isDropMode is true), and ensure the component receives the mode value from
CreateDropActions so the CSV types are only allowed outside drop mode.

---

Nitpick comments:
In `@components/drops/create/utils/file/CreateDropSelectedFilePreview.tsx`:
- Around line 15-29: The getFileType implementation in
CreateDropSelectedFilePreview.tsx duplicates logic found in
CreateDropSelectedFileIcon.tsx; extract that logic into a single exported helper
(e.g., detectFileType in a new helpers/file.helpers.ts) that accepts File | null
and returns FILE_TYPES | null, update both components to import and call
detectFileType, and in CreateDropSelectedFilePreview.tsx map a null result to
FILE_TYPES.UNKNOWN (while the other consumer can keep null) and remove the local
getFileType implementation so the shared helper is the single source of truth.

In `@components/drops/view/item/content/media/MediaDisplay.tsx`:
- Around line 11-19: The MediaType enum and getMediaType detection logic are
duplicated between MediaDisplay.tsx and DropListItemContentMedia.tsx; extract
both into a shared helper (e.g., helpers/mediaType.helpers.ts) exporting the
MediaType enum and getMediaType function, update MediaDisplay.tsx to import
MediaType and getMediaType (references: MediaType, getMediaType) and remove the
local enum/function, and update DropListItemContentMedia.tsx to import the same
shared symbols so both components use the single source of truth for media type
detection.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 61454309-cd22-4d80-a6fd-fbcb8092760a

📥 Commits

Reviewing files that changed from the base of the PR and between 25a3edc and cf473a4.

📒 Files selected for processing (14)
  • __tests__/components/drops/create/utils/CreateDropActionsRow.test.tsx
  • __tests__/components/drops/view/item/content/media/DropListItemContentMedia.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplay.test.tsx
  • __tests__/components/waves/CreateDropActions.test.tsx
  • __tests__/services/uploads/multipartUploadCore.test.ts
  • components/drops/create/utils/CreateDropActionsRow.tsx
  • components/drops/create/utils/file/CreateDropSelectedFileIcon.tsx
  • components/drops/create/utils/file/CreateDropSelectedFilePreview.tsx
  • components/drops/view/item/content/media/DropListItemContentMedia.tsx
  • components/drops/view/item/content/media/DropMediaAttachmentCard.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/CreateDropActions.tsx
  • components/waves/CreateDropContent.tsx
  • services/uploads/multipartUploadCore.ts

Comment thread components/drops/create/utils/CreateDropActionsRow.tsx Outdated
Signed-off-by: GelatoGenesis <tarmokalling@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant