Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PE-242, 243] refactor: editor file handling, image upload status #6442

Open
wants to merge 4 commits into
base: preview
Choose a base branch
from

Conversation

aaryan610
Copy link
Collaborator

@aaryan610 aaryan610 commented Jan 22, 2025

Description

This PR refactors the way editor handles files-

  1. Separated types for editable and read-only file handlers and added restore function to read-only file handler.
  2. Created a new asset.store in the web app to store asset upload status and handle editor uploads for scalability.
  3. Added a new helper function to get the upload status of a file.

New features added-

  1. Users can now see the upload status of an image.

Type of Change

  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring

Summary by CodeRabbit

Based on the comprehensive summary of changes, here are the release notes:

  • New Features

    • Added support for tracking image upload status in the editor
    • Introduced block-specific file upload capabilities
    • Enhanced read-only editor file handling
  • Improvements

    • Refined file upload mechanisms across editor components
    • Updated type definitions for more robust file handling
    • Improved asset management with new hooks and stores
  • Technical Updates

    • Migrated file handling logic from helper functions to hooks
    • Added new editor asset store for managing upload statuses
    • Introduced workspace and block context in file upload processes

These changes primarily focus on enhancing the editor's file upload and asset management capabilities, providing more granular control and improved user experience.

Copy link
Contributor

coderabbitai bot commented Jan 22, 2025

Walkthrough

This pull request introduces a comprehensive refactoring of file handling and upload mechanisms across multiple components in the editor system. The changes primarily focus on enhancing type safety, introducing a new TReadOnlyFileHandler type, and implementing a more robust asset upload tracking system. Key modifications include adding a blockId to upload methods, creating an EditorAssetStore for managing upload statuses, and updating various components to support these new capabilities.

Changes

File/Group Change Summary
packages/editor/src/core/types/config.ts Added TReadOnlyFileHandler type, extended TFileHandler with new properties
packages/editor/src/core/extensions/custom-image/* Updated image upload and handling logic, added upload status tracking
web/core/store/editor/asset.store.ts Introduced EditorAssetStore for managing asset upload statuses
web/core/hooks/editor/use-editor-config.ts Created new hook for managing file handling configurations
Multiple editor components Updated to support workspaceId, modified file upload signatures

Sequence Diagram

sequenceDiagram
    participant User
    participant Editor
    participant AssetStore
    participant FileService
    
    User->>Editor: Upload File
    Editor->>AssetStore: Track Upload (blockId)
    AssetStore->>FileService: Upload Asset
    FileService-->>AssetStore: Upload Progress
    AssetStore->>AssetStore: Update Upload Status
    FileService-->>Editor: Upload Complete
    Editor->>User: File Uploaded
Loading

Possibly related PRs

Suggested Labels

🌟improvement, 🔧refactor, ✨feature

Suggested Reviewers

  • SatishGandham
  • rahulramesha
  • pushya22

Poem

🐰 Hop, hop, upload with glee!
Blocks and files now dance so free
Asset tracking, smooth and bright
CodeRabbit's magic takes its flight
Refactored code, a joyful sight! 🚀

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@aaryan610 aaryan610 changed the title refactor: editor file handling [PE-242, 243] refactor: editor file handling Jan 22, 2025
@aaryan610 aaryan610 marked this pull request as ready for review January 22, 2025 16:45
@aaryan610 aaryan610 changed the title [PE-242, 243] refactor: editor file handling [PE-242, 243] refactor: editor file handling, image upload status Jan 22, 2025
Copy link
Contributor

@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: 8

🔭 Outside diff range comments (2)
web/core/components/issues/issue-detail/issue-activity/root.tsx (1)

Line range hint 94-100: Improve error handling with specific error messages.

The error handling has been oversimplified. Consider capturing and handling specific error types to provide more meaningful feedback to users.

-        } catch {
+        } catch (error) {
+          console.error("Error creating comment:", error);
+          const message = error instanceof Error ? error.message : "Comment creation failed. Please try again later.";
           setToast({
             title: "Error!",
             type: TOAST_TYPE.ERROR,
-            message: "Comment creation failed. Please try again later.",
+            message,
           });
         }

Also applies to: 111-117, 128-134

packages/editor/src/core/hooks/use-file-upload.ts (1)

Line range hint 66-66: Add missing dependencies to useCallback.

The dependency array is missing several dependencies that are used within the callback: editor, blockId, maxFileSize, and loadImageFromFileSystem.

Apply this fix:

    },
-    [onUpload]
+    [editor, blockId, maxFileSize, loadImageFromFileSystem, onUpload]
  );
🧹 Nitpick comments (19)
web/core/components/editor/lite-text-editor/lite-text-editor.tsx (1)

64-65: Consider adding a comment explaining the editor config hook's purpose.

The implementation correctly uses the new useEditorConfig hook to manage file handlers. Consider adding a brief comment explaining its role in the refactored file handling system.

 // editor config
+// Provides file handlers with workspace and project context for the editor
 const { getEditorFileHandlers } = useEditorConfig();
web/core/components/inbox/modals/create-modal/issue-description.tsx (1)

86-97: Consider enhancing error handling and type safety.

While the upload functionality implementation is good, there are a few areas for improvement:

  1. Error handling could be more informative and structured
  2. The data.id usage should be handled more safely as it's optional

Consider this improvement:

  uploadFile={async (blockId, file) => {
    try {
      const { asset_id } = await uploadEditorAsset({
        blockId,
        data: {
-         entity_identifier: data.id ?? "",
+         entity_identifier: data.id || `temp_${Date.now()}`, // Provide a temporary ID if data.id is not available
          entity_type: EFileAssetType.ISSUE_DESCRIPTION,
        },
        file,
        projectId,
        workspaceSlug,
      });
      onAssetUpload?.(asset_id);
      return asset_id;
    } catch (error) {
-     console.log("Error in uploading issue asset:", error);
-     throw new Error("Asset upload failed. Please try again later.");
+     console.error("Error uploading issue asset:", { error, blockId, projectId });
+     throw new Error(`Asset upload failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
  }}
web/core/components/editor/rich-text-editor/rich-text-editor.tsx (1)

21-21: Consider adding JSDoc comments for the uploadFile property.

The type change to TFileHandler["upload"] improves type safety. Consider adding JSDoc comments to document the expected behavior and parameters of the upload function.

+ /** Function to handle file uploads in the editor */
  uploadFile: TFileHandler["upload"];
web/core/components/issues/issue-modal/components/description-editor.tsx (1)

199-212: Enhance error handling and loading state management.

While the upload implementation is good, consider these improvements:

  1. Provide more specific error messages based on error types
  2. Add loading state management to disable the editor during upload
 uploadFile={async (blockId, file) => {
+  const [isUploading, setIsUploading] = useState(false);
   try {
+    setIsUploading(true);
     const { asset_id } = await uploadEditorAsset({
       blockId,
       data: {
         entity_identifier: issueId ?? "",
         entity_type: isDraft
           ? EFileAssetType.DRAFT_ISSUE_DESCRIPTION
           : EFileAssetType.ISSUE_DESCRIPTION,
       },
       file,
       projectId,
       workspaceSlug,
     });
     onAssetUpload(asset_id);
     return asset_id;
   } catch (error) {
-    console.log("Error in uploading issue asset:", error);
-    throw new Error("Asset upload failed. Please try again later.");
+    if (error.status === 413) {
+      throw new Error("File size too large. Please upload a smaller file.");
+    } else if (error.status === 415) {
+      throw new Error("File type not supported.");
+    } else {
+      console.error("Error in uploading issue asset:", error);
+      throw new Error("Asset upload failed. Please try again later.");
+    }
   } finally {
+    setIsUploading(false);
   }
 }}
web/core/store/editor/asset.store.ts (2)

72-76: Re-evaluate the debounce interval for progress updates

The debouncedUpdateProgress function uses a debounce interval of 16 milliseconds, which corresponds to approximately 60fps. Consider if such a high update frequency is necessary for upload progress indicators. A longer interval (e.g., 100ms) might reduce unnecessary renders and improve performance without significantly affecting the user experience.


80-91: Assess the necessity of tempId in upload status

The tempId generated by uuidv4() is assigned to the id field in assetsUploadStatus but doesn't appear to be used elsewhere in the code. If the id is not required for further operations, consider removing it to simplify the status object.

Apply this diff if you choose to remove tempId:

- const tempId = uuidv4();
...
-   set(this.assetsUploadStatus, [blockId], {
-     id: tempId,
+   set(this.assetsUploadStatus, [blockId], {
      name: file.name,
      progress: 0,
      size: file.size,
      type: file.type,
    });
packages/editor/src/core/extensions/custom-image/components/upload-status.tsx (1)

17-21: Enhance accessibility and error handling.

The upload status indicator needs improvements in the following areas:

  1. Add ARIA attributes for screen readers
  2. Handle edge cases like upload failures
  3. Consider adding a loading state

Consider applying these changes:

  return (
    <div 
      className="absolute top-1 right-1 z-20 bg-black/60 rounded text-xs font-medium w-10 text-center"
+     role="progressbar"
+     aria-valuenow={uploadStatus}
+     aria-valuemin="0"
+     aria-valuemax="100"
+     aria-label="Image upload progress"
    >
-     {uploadStatus}%
+     {uploadStatus !== undefined ? `${uploadStatus}%` : 'Loading...'}
    </div>
  );
packages/editor/src/core/types/config.ts (1)

Line range hint 8-17: Consider enhancing type documentation.

The type structure looks good, but could benefit from additional JSDoc comments explaining the purpose of each property.

Consider adding documentation:

 export type TFileHandler = TReadOnlyFileHandler & {
+  /** Maps block IDs to their upload progress (0-100) */
   assetsUploadStatus: Record<string, number>;
+  /** Cancels ongoing upload operations */
   cancel: () => void;
+  /** Handles asset deletion */
   delete: DeleteImage;
+  /** Handles asset upload */
   upload: UploadImage;
   validation: {
     /**
      * @description max file size in bytes
      * @example enter 5242880( 5* 1024 * 1024) for 5MB
      */
     maxFileSize: number;
   };
 };
space/core/components/editor/lite-text-read-only-editor.tsx (1)

15-15: LGTM! Consider making workspaceId required.

The addition of workspaceId and its integration with getReadOnlyEditorFileHandlers is well-implemented. The changes align with the PR objectives of refactoring file handling.

Consider marking workspaceId as required in the type definition by moving it outside the intersection:

type LiteTextReadOnlyEditorWrapperProps = {
  workspaceId: string;
  anchor: string;
} & Omit<
  ILiteTextReadOnlyEditor,
  "disabledExtensions" | "fileHandler" | "mentionHandler"
>;

Also applies to: 19-26

space/core/components/editor/rich-text-editor.tsx (1)

3-3: LGTM! Consider adding JSDoc comments.

The changes improve type safety by using TFileHandler["upload"] and properly integrate the new workspaceId and anchor props. The implementation aligns well with the PR objectives.

Consider adding JSDoc comments to document the new props:

interface RichTextEditorWrapperProps
  extends Omit<IRichTextEditor, "disabledExtensions" | "fileHandler" | "mentionHandler"> {
  /** Unique identifier for the editor instance */
  anchor: string;
  /** Function to handle file uploads */
  uploadFile: TFileHandler["upload"];
  /** ID of the workspace context */
  workspaceId: string;
}

Also applies to: 11-13, 17-17, 27-29

space/core/components/issues/peek-overview/issue-details.tsx (1)

16-18: Consider using consistent casing for workspaceID.

The variable uses uppercase "ID" while the prop uses lowercase "Id". While functionally correct, maintaining consistent casing would improve code readability.

-  const { project_details, workspace: workspaceID } = usePublish(anchor);
+  const { project_details, workspace: workspaceId } = usePublish(anchor);
packages/editor/src/core/hooks/use-read-only-editor.ts (1)

14-14: LGTM! Type changes enhance type safety for read-only operations.

The switch to TReadOnlyFileHandler properly enforces read-only behavior at the type system level.

Consider adding JSDoc comments to document the read-only nature of the fileHandler property:

+ /** File handler with read-only operations */
  fileHandler: TReadOnlyFileHandler;

Also applies to: 23-23

web/core/components/issues/issue-detail/issue-activity/comments/comment-create.tsx (1)

113-117: LGTM! File upload handler correctly implements the new signature.

The changes properly integrate with the new file handling mechanism while maintaining state management.

Consider extracting the file upload handler type for better type safety:

type FileUploadHandler = (blockId: string, file: File) => Promise<string>;
packages/editor/src/core/types/editor.ts (1)

19-19: LGTM! Well-structured type definitions.

The addition of TReadOnlyFileHandler and attachment-related types enhances type safety and provides proper typing for the new attachment functionality. The changes are consistent with TypeScript best practices.

Consider documenting the new types with JSDoc comments for better developer experience.

+/** Handler for read-only file operations */
 TReadOnlyFileHandler,

+/** Commands supported by the editor */
 export type TEditorCommands =

+/** Extra properties required for specific commands */
 export type TCommandExtraProps =

Also applies to: 48-49, 55-57, 162-162

web/core/components/issues/description-input.tsx (1)

131-142: Enhance error handling in uploadFile.

While the implementation looks good, the error handling could be improved:

  1. The error message could be more specific based on the error type
  2. Consider adding error tracking/logging
 } catch (error) {
-    console.log("Error in uploading issue asset:", error);
-    throw new Error("Asset upload failed. Please try again later.");
+    console.error("Error uploading issue asset:", error);
+    // Track error for monitoring
+    if (error instanceof TypeError) {
+      throw new Error("Invalid file format. Please try again with a supported file type.");
+    } else {
+      throw new Error("Asset upload failed. Please try again later.");
+    }
 }
packages/editor/src/core/extensions/custom-image/custom-image.ts (1)

36-36: Consider initializing assetsUploadStatus with an empty object.

The assetsUploadStatus is added to storage but its initial value is undefined. Consider initializing it with an empty object to prevent potential undefined access issues.

  addStorage() {
    return {
      fileMap: new Map(),
      deletedImageSet: new Map<string, boolean>(),
      uploadInProgress: false,
      maxFileSize,
      markdown: {
        serialize() {},
      },
-     assetsUploadStatus,
+     assetsUploadStatus: assetsUploadStatus ?? {},
    };
  }

Also applies to: 133-133

packages/editor/src/core/hooks/use-editor.ts (1)

130-133: Add a safety check for editor commands.

Consider adding a safety check for the editor commands to prevent potential issues if they're not initialized:

   if (!editor) return;
+  if (!editor.commands?.updateAssetsUploadStatus) return;
   const assetsUploadStatus = fileHandler.assetsUploadStatus;
   editor.commands.updateAssetsUploadStatus(assetsUploadStatus);
packages/editor/src/core/extensions/custom-image/components/image-block.tsx (1)

214-215: Consider a more comprehensive condition for upload status visibility.

The current condition might not cover all cases where upload status should be shown.

-  const showUploadStatus = !resolvedImageSrc;
+  const showUploadStatus = !resolvedImageSrc && !hasErroredOnFirstLoad && !hasTriedRestoringImageOnce;

This ensures that upload status is not shown when:

  1. The image has errored on first load
  2. We've already tried restoring the image
packages/editor/src/core/hooks/use-file-upload.ts (1)

Line range hint 156-187: Consider enhancing error handling and validation.

The error handling in uploadFirstImageAndInsertRemaining could be improved:

  1. Console warnings/errors should be propagated to the UI for better user feedback.
  2. File validation could be more robust (e.g., checking file types using magic numbers).

Would you like me to provide a more detailed implementation for these improvements?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f3a0be and 873981f.

📒 Files selected for processing (53)
  • packages/editor/src/core/components/editors/document/read-only-editor.tsx (2 hunks)
  • packages/editor/src/core/extensions/custom-image/components/image-block.tsx (3 hunks)
  • packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx (1 hunks)
  • packages/editor/src/core/extensions/custom-image/components/upload-status.tsx (1 hunks)
  • packages/editor/src/core/extensions/custom-image/custom-image.ts (5 hunks)
  • packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts (2 hunks)
  • packages/editor/src/core/extensions/extensions.tsx (1 hunks)
  • packages/editor/src/core/extensions/image/read-only-image.tsx (1 hunks)
  • packages/editor/src/core/extensions/read-only-extensions.tsx (2 hunks)
  • packages/editor/src/core/hooks/use-editor.ts (1 hunks)
  • packages/editor/src/core/hooks/use-file-upload.ts (2 hunks)
  • packages/editor/src/core/hooks/use-read-only-editor.ts (2 hunks)
  • packages/editor/src/core/types/collaboration.ts (2 hunks)
  • packages/editor/src/core/types/config.ts (1 hunks)
  • packages/editor/src/core/types/editor.ts (3 hunks)
  • packages/editor/src/core/types/image.ts (1 hunks)
  • space/core/components/editor/lite-text-editor.tsx (2 hunks)
  • space/core/components/editor/lite-text-read-only-editor.tsx (1 hunks)
  • space/core/components/editor/rich-text-editor.tsx (2 hunks)
  • space/core/components/editor/rich-text-read-only-editor.tsx (1 hunks)
  • space/core/components/issues/peek-overview/comment/add-comment.tsx (1 hunks)
  • space/core/components/issues/peek-overview/comment/comment-detail-card.tsx (2 hunks)
  • space/core/components/issues/peek-overview/issue-details.tsx (2 hunks)
  • space/helpers/editor.helper.ts (3 hunks)
  • web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/[pageId]/page.tsx (6 hunks)
  • web/ce/components/pages/editor/ai/ask-pi-menu.tsx (3 hunks)
  • web/ce/components/pages/editor/ai/menu.tsx (3 hunks)
  • web/core/components/core/modals/gpt-assistant-popover.tsx (6 hunks)
  • web/core/components/editor/lite-text-editor/lite-text-editor.tsx (3 hunks)
  • web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx (1 hunks)
  • web/core/components/editor/rich-text-editor/rich-text-editor.tsx (2 hunks)
  • web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx (1 hunks)
  • web/core/components/editor/sticky-editor/editor.tsx (3 hunks)
  • web/core/components/inbox/modals/create-modal/issue-description.tsx (3 hunks)
  • web/core/components/issues/description-input.tsx (4 hunks)
  • web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx (2 hunks)
  • web/core/components/issues/issue-detail/issue-activity/comments/comment-create.tsx (1 hunks)
  • web/core/components/issues/issue-detail/issue-activity/root.tsx (7 hunks)
  • web/core/components/issues/issue-modal/components/description-editor.tsx (4 hunks)
  • web/core/components/pages/editor/editor-body.tsx (5 hunks)
  • web/core/components/pages/editor/page-root.tsx (3 hunks)
  • web/core/components/pages/version/editor.tsx (3 hunks)
  • web/core/components/profile/activity/activity-list.tsx (3 hunks)
  • web/core/components/profile/activity/profile-activity-list.tsx (1 hunks)
  • web/core/hooks/editor/index.ts (1 hunks)
  • web/core/hooks/editor/use-editor-config.ts (1 hunks)
  • web/core/hooks/store/index.ts (1 hunks)
  • web/core/hooks/store/use-editor-asset.ts (1 hunks)
  • web/core/services/file.service.ts (5 hunks)
  • web/core/store/editor/asset.store.ts (1 hunks)
  • web/core/store/issue/issue-details/attachment.store.ts (1 hunks)
  • web/core/store/root.store.ts (4 hunks)
  • web/helpers/editor.helper.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • web/helpers/editor.helper.ts
✅ Files skipped from review due to trivial changes (2)
  • web/core/hooks/editor/index.ts
  • packages/editor/src/core/extensions/extensions.tsx
🔇 Additional comments (68)
web/core/components/editor/lite-text-editor/lite-text-editor.tsx (3)

5-5: LGTM! Import changes align with file handling refactor.

The addition of TFileHandler type and useEditorConfig hook imports support the PR's objective of improving file handling mechanisms.

Also applies to: 12-12


30-30: LGTM! Type-safe interface update.

The change to use TFileHandler["upload"] improves type safety and aligns with the separation of editable and read-only file handlers.


Line range hint 1-120: Great implementation of the file handling refactor!

The changes successfully:

  • Improve type safety with TFileHandler
  • Properly integrate the new editor configuration system
  • Maintain clean code structure and React best practices

The implementation aligns perfectly with the PR objectives of refactoring the editor's file handling mechanism.

web/core/components/editor/sticky-editor/editor.tsx (4)

5-5: LGTM! Import changes align with type safety improvements.

The addition of TFileHandler type import supports the PR's objective of improving file handler type definitions.


11-11: LGTM! Hook-based approach improves editor configuration management.

The switch to useEditorConfig hook aligns with React best practices and provides better integration with the component lifecycle.


28-28: LGTM! Type definition improvement enhances maintainability.

Using TFileHandler["upload"] instead of an inline function type ensures consistency with the centralized type system and makes future updates easier to manage.


52-53: LGTM! Hook usage properly implements editor configuration.

The useEditorConfig hook is correctly implemented, and the destructured getEditorFileHandlers function is appropriately used within the component.

web/core/components/inbox/modals/create-modal/issue-description.tsx (2)

20-20: LGTM! Import changes align with the refactoring objectives.

The addition of useEditorAsset hook import is consistent with the PR's goal of refactoring the file handling mechanism.


51-52: LGTM! Hook implementation is clean and well-placed.

The uploadEditorAsset hook is correctly extracted and placed with other store hooks.

space/core/components/issues/peek-overview/comment/comment-detail-card.tsx (2)

143-143: LGTM! Consistent workspace ID handling.

The addition of the workspaceId prop to LiteTextReadOnlyEditor maintains consistency with the editable editor component.


115-118: LGTM! Verify other usages of uploadFile.

The updated uploadFile signature correctly implements the new file handling mechanism.

Let's verify that all other components using uploadFile have been updated to include the blockId parameter:

✅ Verification successful

All usages of uploadFile properly implement the blockId parameter

The codebase consistently implements the updated uploadFile signature with blockId parameter across all components using LiteTextEditor. The type system ensures compliance through the TFileHandler interface.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for uploadFile prop usage in components
ast-grep --pattern 'uploadFile={$_}' .

Length of output: 40


Script:

#!/bin/bash
# Search for LiteTextEditor component usage with context
rg "LiteTextEditor" -A 5 -B 5

# Backup search for uploadFile occurrences
rg "uploadFile" -A 2 -B 2

Length of output: 47447

web/core/components/editor/rich-text-editor/rich-text-editor.tsx (2)

3-3: LGTM! Import changes align with file handling refactor.

The addition of TFileHandler type and useEditorConfig hook supports better type safety and modular configuration management.

Also applies to: 11-11


Line range hint 33-44: Verify that all required parameters are properly propagated to child components.

The implementation correctly uses the useEditorConfig hook and passes all necessary parameters to getEditorFileHandlers. This change improves modularity and configuration management.

Let's verify that all required parameters are properly typed and used in child components:

✅ Verification successful

Parameters are properly propagated and type-safe across all components

The verification confirms:

  • Consistent parameter passing across all editor components
  • Proper type definitions and inheritance (TFileHandler extends TReadOnlyFileHandler)
  • Correct usage of read-only vs. writable handlers based on component needs
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for getEditorFileHandlers usage to ensure consistent parameter passing
ast-grep --pattern 'getEditorFileHandlers({
  $$$
})'

# Search for TFileHandler usage to verify type consistency
rg -t typescript "TFileHandler" -A 2

Length of output: 4918


Script:

#!/bin/bash
# Search for type definitions and useEditorConfig implementation
rg "type.*FileHandler" -g "*.ts*" -A 2

# Find useEditorConfig implementation
ast-grep --pattern 'export function useEditorConfig() {
  $$$
}'

# Alternative search for useEditorConfig
rg "useEditorConfig" -g "*.ts*" -A 5

Length of output: 10733

web/core/components/pages/editor/page-root.tsx (1)

7-7: LGTM! Clean integration of webhook connection parameters.

The changes properly integrate webhook connection parameters throughout the component hierarchy, maintaining consistency in the data flow.

Also applies to: 39-39, 44-44, 120-120

web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/[pageId]/page.tsx (1)

116-122: LGTM! Well-structured webhook configuration.

The webhook connection parameters are properly memoized and include all necessary fields.

web/core/components/pages/editor/editor-body.tsx (1)

133-142: LGTM! Clean realtime configuration setup.

The realtime configuration is properly set up with webhook parameters and includes good error handling.

web/core/components/issues/issue-detail/issue-activity/root.tsx (1)

136-154: LGTM! Well-structured asset upload handling.

The uploadCommentAsset function properly handles file uploads with the new blockId parameter and includes appropriate error handling.

web/core/components/issues/issue-modal/components/description-editor.tsx (2)

77-77: LGTM! Good use of custom hook for asset management.

The introduction of useEditorAsset hook aligns well with the PR's objective of refactoring file handling and provides a centralized way to manage editor assets.


30-31: Consider moving service instantiation inside the component.

Moving service instantiations outside the component could cause issues if these services require runtime configuration. Consider moving them inside the component or using a dependency injection pattern.

Let's check if these services require runtime configuration:

web/core/store/editor/asset.store.ts (1)

85-91: Confirm all state mutations occur within actions

While you are using runInAction to wrap state mutations, double-check that all modifications to assetsUploadStatus are appropriately enclosed within actions to adhere to MobX best practices and ensure proper reactivity.

packages/editor/src/core/types/image.ts (1)

5-5: Update of UploadImage type signature is appropriate

The inclusion of blockId in the UploadImage type allows image uploads to be associated with specific editor blocks, enhancing upload management and tracking.

web/core/hooks/store/use-editor-asset.ts (1)

6-10: Implementation of useEditorAsset hook is correct

The custom hook correctly accesses the StoreContext and returns editorAssetStore. The error handling ensures that it's used within a StoreProvider, preventing potential undefined behavior.

packages/editor/src/core/types/config.ts (1)

3-6: LGTM! Clear separation of read-only file handling concerns.

The introduction of TReadOnlyFileHandler type effectively separates read-only operations from editable ones.

packages/editor/src/core/extensions/image/read-only-image.tsx (1)

6-8: LGTM! Proper adoption of the new type system.

The change from Pick<TFileHandler, "getAssetSrc"> to TReadOnlyFileHandler aligns well with the new type separation.

web/core/hooks/store/index.ts (1)

10-10: LGTM! Clean integration of the new editor asset hook.

The export is properly placed and maintains the alphabetical ordering of the barrel file.

space/core/components/editor/rich-text-read-only-editor.tsx (1)

15-15: LGTM! Implementation maintains consistency.

The changes mirror those in the lite editor, maintaining consistency across components. The addition of workspaceId is properly integrated with getReadOnlyEditorFileHandlers.

Also applies to: 19-26

packages/editor/src/core/types/collaboration.ts (1)

12-12: LGTM! Type separation improves clarity.

The separation of TReadOnlyFileHandler from TFileHandler and its integration in TReadOnlyCollaborativeEditorProps improves type safety and clarity. This change aligns perfectly with the PR objective of separating types for editable and read-only file handlers.

Also applies to: 47-47

space/core/components/issues/peek-overview/issue-details.tsx (1)

38-38: LGTM! Proper null handling.

The nullish coalescing operator ensures safe handling of undefined workspaceID.

packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts (2)

7-9: LGTM! Improved type safety with dedicated read-only handler.

The change from Pick<TFileHandler> to TReadOnlyFileHandler better represents the read-only nature of this component.


59-59: Verify upload status initialization.

The empty object initialization for assetsUploadStatus is correct, but ensure that consumers properly handle this empty state.

✅ Verification successful

Empty object initialization for assetsUploadStatus is safe and properly handled

The codebase shows proper handling of the empty state through type safety, null checks, and robust state management patterns.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for places where assetsUploadStatus is accessed
rg -A 3 "assetsUploadStatus" --type ts

Length of output: 5806

web/core/components/editor/rich-text-editor/rich-text-read-only-editor.tsx (3)

8-9: LGTM! Improved code organization with hook.

Moving to useEditorConfig hook enhances maintainability and reusability.

Also applies to: 26-27


17-17: LGTM! Type safety enhancement.

Adding workspaceId to props type ensures proper type checking.


34-36: LGTM! Consistent workspace context propagation.

Properly passing workspace context to file handlers.

web/core/components/editor/lite-text-editor/lite-text-read-only-editor.tsx (1)

8-9: LGTM! Consistent implementation with rich text editor.

The changes mirror those in the rich text editor, maintaining consistency across editor variants:

  • Added workspaceId to props
  • Switched to useEditorConfig hook
  • Updated file handler configuration

Also applies to: 17-17, 26-27, 34-36

space/helpers/editor.helper.ts (2)

Line range hint 28-47: LGTM! Well-structured read-only file handler implementation.

The separation of read-only file handlers with distinct responsibilities (getAssetSrc and restore) improves code organization and maintainability.


54-75: LGTM! Clean composition of file handlers.

Good use of composition by spreading read-only handlers and adding editable-specific functionality.

packages/editor/src/core/components/editors/document/read-only-editor.tsx (1)

13-19: LGTM! Improved type safety for read-only editor.

The use of TReadOnlyFileHandler instead of Pick<TFileHandler, "getAssetSrc"> provides better type safety and aligns with the separation of concerns.

Also applies to: 29-29

space/core/components/editor/lite-text-editor.tsx (1)

3-3: LGTM! Improved type consistency.

Good use of TFileHandler["upload"] type to ensure consistency with the file handler interface.

Also applies to: 17-17

web/core/hooks/editor/use-editor-config.ts (2)

21-96: LGTM! Well-structured editor configuration hook.

The hook provides a clean separation between read-only and editable file handlers, with proper dependency management in useCallback hooks.


37-44: ⚠️ Potential issue

Add null check for optional projectId.

The projectId parameter is optional but used without a null check in getAssetSrc.

Add null check to handle cases where projectId is undefined:

  return (
    getEditorAssetSrc({
      assetId: path,
-     projectId,
+     projectId: projectId ?? undefined,
      workspaceSlug,
    }) ?? ""
  );

Likely invalid or redundant comment.

space/core/components/issues/peek-overview/comment/add-comment.tsx (1)

Line range hint 93-97: LGTM! The updated file upload handler correctly implements the new signature.

The changes align with the refactoring objectives, maintaining proper state management and error handling.

packages/editor/src/core/extensions/read-only-extensions.tsx (2)

32-33: LGTM! Type changes maintain consistency with read-only pattern.

The switch to TReadOnlyFileHandler aligns with the type separation objectives.

Also applies to: 37-37


97-102: LGTM! Simplified image extension configuration.

Direct passing of fileHandler to both image extensions improves code clarity.

web/ce/components/pages/editor/ai/ask-pi-menu.tsx (2)

9-10: LGTM! Workspace context integration looks good.

The addition of the workspace context through the useWorkspace hook and the derived workspaceId enhances the component's integration with the workspace-specific functionality.

Also applies to: 24-27


49-51: Verify error handling for undefined workspaceId.

While the implementation looks good, consider the case where workspaceId is an empty string. Ensure that the RichTextReadOnlyEditor component handles this gracefully.

web/core/components/pages/version/editor.tsx (2)

12-13: LGTM! Clean hooks integration.

The integration of useEditorConfig and useWorkspace hooks, along with the workspace context derivation, is well-structured and follows React best practices.

Also applies to: 30-33, 36-37


106-108: Verify the impact of workspaceId on file handling.

The addition of workspaceId to the file handler configuration looks good. However, let's verify that all file operations handle undefined workspace IDs gracefully.

✅ Verification successful

Workspace ID handling in file operations is properly implemented

The codebase demonstrates robust handling of undefined workspace IDs through consistent null coalescing and type-safe implementations across both read-only and editable file handlers.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for file handler implementations to verify workspace ID handling
ast-grep --pattern 'getReadOnlyEditorFileHandlers({
  $$$
  workspaceId: $_
  $$$
})'

Length of output: 87


Script:

#!/bin/bash
# Search for file handler related code
rg -i "filehandler" -A 5 -B 5

# Also search for workspace ID usage in TypeScript files
rg "workspaceId.*file" -g "*.ts" -g "*.tsx" -A 5 -B 5

Length of output: 66031

web/core/components/issues/description-input.tsx (2)

18-18: LGTM! Clean hook integration.

The addition of useEditorAsset hook is well-placed and follows React best practices.

Also applies to: 54-55


155-157: LGTM! Proper workspace context integration.

The addition of workspaceId to RichTextReadOnlyEditor is consistent with the broader refactoring pattern.

packages/editor/src/core/extensions/custom-image/custom-image.ts (1)

24-25: LGTM: Command interface updates align with the PR objectives.

The addition of blockId parameter to uploadImage and the new updateAssetsUploadStatus command enhance the file handling capabilities as intended.

packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx (1)

71-71: LGTM: Proper integration of blockId parameter.

The addition of blockId parameter to useUploader hook is consistent with the file handling refactor.

web/core/store/root.store.ts (1)

10-10: LGTM: Clean integration of EditorAssetStore.

The EditorAssetStore is properly integrated into the root store with appropriate initialization in both constructor and resetOnSignOut method.

Also applies to: 64-64, 94-94, 127-127

web/core/store/issue/issue-details/attachment.store.ts (1)

129-129: LGTM: Improved encapsulation of debouncedUpdateProgress.

Making the method private is a good practice as it's an internal implementation detail.

web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx (2)

162-164: LGTM! File upload handling improved with block-specific tracking.

The updated uploadFile function now correctly associates uploads with specific blocks, improving tracking and management of file uploads within the editor.


204-207: LGTM! Enhanced workspace context handling.

The addition of workspaceId prop to LiteTextReadOnlyEditor improves context handling and maintains consistency with other components.

web/core/services/file.service.ts (2)

68-69: LGTM! Enhanced file upload with progress tracking.

The addition of uploadProgressHandler enables real-time upload progress monitoring, improving user experience during file uploads.

Also applies to: 79-83


131-132: LGTM! Consistent progress tracking implementation.

The same progress tracking capability is correctly implemented for project assets, maintaining consistency across the service.

Also applies to: 142-146

web/core/components/profile/activity/activity-list.tsx (2)

18-18: LGTM! Improved workspace context handling.

The addition of workspace context retrieval with proper null checks enhances type safety and maintains consistency.

Also applies to: 30-32


85-87: LGTM! Consistent workspace context propagation.

The workspaceId is correctly passed to the editor component, maintaining consistency with other components.

web/core/components/core/modals/gpt-assistant-popover.tsx (3)

9-10: Improved type safety by using specific editor ref type.

Replacing any with EditorReadOnlyRefApi enhances type safety and maintainability.

Also applies to: 57-58


28-31: LGTM! Enhanced workspace context handling in props.

The addition of workspace-related props improves component integration and maintains consistency.

Also applies to: 48-51


225-228: LGTM! Consistent workspace context propagation to editors.

The workspaceId is correctly passed to both editor instances, maintaining consistency across the component.

Also applies to: 238-241

web/core/components/profile/activity/profile-activity-list.tsx (1)

106-107: LGTM! Workspace identifiers are properly passed.

The changes correctly pass both workspaceId and workspaceSlug to the RichTextReadOnlyEditor component, maintaining consistency with the refactored file handling system.

packages/editor/src/core/hooks/use-editor.ts (1)

128-134: LGTM! Upload status sync is implemented.

The new effect properly syncs the assets upload status between the file handler and editor commands.

web/ce/components/pages/editor/ai/menu.tsx (1)

24-24: LGTM! Workspace context is properly integrated.

The changes correctly:

  1. Add workspaceId to the Props type
  2. Destructure it from props
  3. Pass it to the RichTextReadOnlyEditor component

Also applies to: 62-62, 219-220

packages/editor/src/core/extensions/custom-image/components/image-block.tsx (1)

7-7: LGTM! Upload status visualization is implemented.

The changes properly integrate the ImageUploadStatus component to show upload progress for images.

Also applies to: 214-215, 276-276

packages/editor/src/core/hooks/use-file-upload.ts (2)

17-17: LGTM!

The destructuring properly includes the new blockId parameter.


9-9: Verify all consumers of useUploader hook provide blockId.

The addition of the required blockId property is a breaking change that affects all consumers of the useUploader hook.

Let's verify all consumers are updated:

✅ Verification successful

✓ All consumers of useUploader hook are properly updated

The only consumer in packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx correctly provides the blockId parameter.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all usages of useUploader to ensure they provide blockId
ast-grep --pattern 'useUploader({$$$})'

Length of output: 799

Comment on lines +96 to +106
uploadFile: async (blockId, file) => {
const { asset_id } = await uploadEditorAsset({
blockId,
data: {
entity_identifier: id ?? "",
entity_type: EFileAssetType.PAGE_DESCRIPTION,
},
file
);
file,
projectId: projectId?.toString() ?? "",
workspaceSlug: workspaceSlug?.toString() ?? "",
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling to the uploadFile function.

The uploadFile function should include error handling to gracefully handle upload failures and provide user feedback.

 uploadFile: async (blockId, file) => {
+  try {
     const { asset_id } = await uploadEditorAsset({
       blockId,
       data: {
         entity_identifier: id ?? "",
         entity_type: EFileAssetType.PAGE_DESCRIPTION,
       },
       file,
       projectId: projectId?.toString() ?? "",
       workspaceSlug: workspaceSlug?.toString() ?? "",
     });
     return asset_id;
+  } catch (error) {
+    console.error("Error uploading file:", error);
+    throw new Error("Failed to upload file. Please try again.");
+  }
 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uploadFile: async (blockId, file) => {
const { asset_id } = await uploadEditorAsset({
blockId,
data: {
entity_identifier: id ?? "",
entity_type: EFileAssetType.PAGE_DESCRIPTION,
},
file
);
file,
projectId: projectId?.toString() ?? "",
workspaceSlug: workspaceSlug?.toString() ?? "",
});
uploadFile: async (blockId, file) => {
try {
const { asset_id } = await uploadEditorAsset({
blockId,
data: {
entity_identifier: id ?? "",
entity_type: EFileAssetType.PAGE_DESCRIPTION,
},
file,
projectId: projectId?.toString() ?? "",
workspaceSlug: workspaceSlug?.toString() ?? "",
});
return asset_id;
} catch (error) {
console.error("Error uploading file:", error);
throw new Error("Failed to upload file. Please try again.");
}
},

// derived values
const { id: pageId, name: pageTitle, isContentEditable, updateTitle } = page;
const workspaceId = getWorkspaceBySlug(workspaceSlug)?.id ?? "";
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add null check for workspaceId derivation.

The workspaceId derivation should include a null check to prevent potential runtime errors.

-  const workspaceId = getWorkspaceBySlug(workspaceSlug)?.id ?? "";
+  const workspace = getWorkspaceBySlug(workspaceSlug);
+  if (!workspace?.id) {
+    console.error("Failed to get workspace ID");
+  }
+  const workspaceId = workspace?.id ?? "";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const workspaceId = getWorkspaceBySlug(workspaceSlug)?.id ?? "";
const workspace = getWorkspaceBySlug(workspaceSlug);
if (!workspace?.id) {
console.error("Failed to get workspace ID");
}
const workspaceId = workspace?.id ?? "";

@@ -76,8 +72,10 @@ export const IssueDescriptionEditor: React.FC<TIssueDescriptionEditorProps> = ob
const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false);
// store hooks
const { getWorkspaceBySlug } = useWorkspace();
const workspaceId = getWorkspaceBySlug(workspaceSlug?.toString())?.id as string;
const workspaceId = getWorkspaceBySlug(workspaceSlug?.toString())?.id ?? "";
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Validate workspace ID before usage.

Using an empty string as a fallback for workspaceId could lead to silent failures. Consider throwing an error or handling the missing workspace ID case explicitly.

-  const workspaceId = getWorkspaceBySlug(workspaceSlug?.toString())?.id ?? "";
+  const workspace = getWorkspaceBySlug(workspaceSlug?.toString());
+  const workspaceId = workspace?.id;
+  if (!workspaceId) {
+    console.error("Workspace not found for slug:", workspaceSlug);
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const workspaceId = getWorkspaceBySlug(workspaceSlug?.toString())?.id ?? "";
const workspace = getWorkspaceBySlug(workspaceSlug?.toString());
const workspaceId = workspace?.id;
if (!workspaceId) {
console.error("Workspace not found for slug:", workspaceSlug);
}

Comment on lines +117 to +119
delete this.assetsUploadStatus[blockId];
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure proper mutation of observables when deleting properties

Directly deleting properties from an observable object may not trigger reactivity in MobX. To ensure that observers are notified when an upload status is removed, consider using runInAction with the set function to assign undefined, or use an observable Map for assetsUploadStatus.

Apply this diff to modify the deletion:

runInAction(() => {
- delete this.assetsUploadStatus[blockId];
+ set(this.assetsUploadStatus, blockId, undefined);
});

Alternatively, initialize assetsUploadStatus as an observable map:

- assetsUploadStatus: Record<string, TAttachmentUploadStatus> = {};
+ assetsUploadStatus = observable.map<string, TAttachmentUploadStatus>();

And update usages accordingly.

Committable suggestion skipped: line range outside the PR's diff.

anchor,
workspaceId,
}),
getAssetUploadStatus: () => 0,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix hardcoded upload status.

The getAssetUploadStatus method returns a hardcoded value of 0, which doesn't reflect the actual upload status.

Consider implementing proper upload status tracking or using the upload status from the asset store:

-    getAssetUploadStatus: () => 0,
+    getAssetUploadStatus: (blockId: string) => assetStore.getUploadStatus(blockId),

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +74 to +81
await fileService.deleteNewAsset(
getEditorAssetSrc({
assetId: src,
projectId,
workspaceSlug,
}) ?? ""
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for optional projectId in delete method.

Similar to getAssetSrc, the delete method uses projectId without a null check.

Add null check:

  await fileService.deleteNewAsset(
    getEditorAssetSrc({
      assetId: src,
-     projectId,
+     projectId: projectId ?? undefined,
      workspaceSlug,
    }) ?? ""
  );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await fileService.deleteNewAsset(
getEditorAssetSrc({
assetId: src,
projectId,
workspaceSlug,
}) ?? ""
);
}
await fileService.deleteNewAsset(
getEditorAssetSrc({
assetId: src,
projectId: projectId ?? undefined,
workspaceSlug,
}) ?? ""
);
}

Comment on lines +188 to +194
uploadImage: (blockId, file) => async () => {
const fileUrl = await upload(blockId, file);
return fileUrl;
},
getImageSource: (path: string) => async () => await getAssetSrc(path),
restoreImage: (src: string) => async () => {
updateAssetsUploadStatus: (updatedStatus) => () => {
this.storage.assetsUploadStatus = updatedStatus;
},
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Add error handling to uploadImage command

The uploadImage command should include try-catch block to handle upload failures gracefully, consistent with other error handling patterns in the codebase:

uploadImage: (blockId, file) => async () => {
  try {
    const fileUrl = await upload(blockId, file);
    return fileUrl;
  } catch (error) {
    console.error("Error uploading image:", error);
    throw error;
  }
},
🔗 Analysis chain

Verify error handling in uploadImage command.

The uploadImage command should handle potential upload failures gracefully.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for error handling patterns in upload-related code
rg -A 5 "upload.*catch|upload.*error" 

Length of output: 4859


Script:

#!/bin/bash
# Find upload function implementation and its usage
ast-grep --pattern 'function upload($$$) { $$$ }'
ast-grep --pattern 'const upload = ($$$) => { $$$ }'
rg -A 10 "uploadImage.*try|try.*uploadImage"

Length of output: 153


Script:

#!/bin/bash
# Find the complete implementation and imports
fd "custom-image.ts" --exec cat {}
rg -g "custom-image*" "try|catch|error"

Length of output: 7867

@@ -49,7 +50,7 @@ export const useUploader = (args: TUploaderArgs) => {
reader.readAsDataURL(fileWithTrimmedName);
// @ts-expect-error - TODO: fix typings, and don't remove await from
// here for now
const url: string = await editor?.commands.uploadImage(fileWithTrimmedName);
const url: string = await editor?.commands.uploadImage(blockId, fileWithTrimmedName);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix the TODO comment and improve error handling.

Several improvements needed:

  1. The TODO comment about typings should be addressed.
  2. The error handling could be more specific about what went wrong during upload.

Consider this improvement:

-        // @ts-expect-error - TODO: fix typings, and don't remove await from
-        // here for now
-        const url: string = await editor?.commands.uploadImage(blockId, fileWithTrimmedName);
+        if (!editor?.commands.uploadImage) {
+          throw new Error("Upload command not available");
+        }
+        const url = await editor.commands.uploadImage(blockId, fileWithTrimmedName);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const url: string = await editor?.commands.uploadImage(blockId, fileWithTrimmedName);
if (!editor?.commands.uploadImage) {
throw new Error("Upload command not available");
}
const url = await editor.commands.uploadImage(blockId, fileWithTrimmedName);

@aaryan610 aaryan610 added this to the v0.24.0 milestone Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant