Skip to content

[WEB-1116] feat: pages realtime collaboration#5493

Merged
sriramveeraghanta merged 29 commits intopreviewfrom
pages-live-server
Sep 2, 2024
Merged

[WEB-1116] feat: pages realtime collaboration#5493
sriramveeraghanta merged 29 commits intopreviewfrom
pages-live-server

Conversation

@aaryan610
Copy link
Member

@aaryan610 aaryan610 commented Sep 2, 2024

What's new?

Introducing Realtime Pages

Media:

Screen.Recording.2024-09-02.at.17.29.57.mov

Plane issue: WEB-1116

Summary by CodeRabbit

  • New Features

    • Introduced a new job in the CI/CD pipeline for deploying a live server image based on specific conditions.
    • Added a new service for the live environment in Docker configurations, enhancing deployment capabilities.
    • Implemented collaborative editing features in the editor, including new components and hooks for real-time collaboration.
    • Added support for a read-only collaborative editor.
  • Bug Fixes

    • Updated the react-hook-form dependency to include recent bug fixes and improvements.
  • Documentation

    • Added example environment variables for the live setup to improve configuration clarity.
  • Chores

    • Updated various configuration files to streamline the build process and improve project organization.

aaryan610 and others added 29 commits July 26, 2024 17:48
* init: live server for editor realtime sync

* chore: authentication added

* chore: updated logic to convert html to binary for old pages

* chore: added description json on page update

* chore: made all functions generic

* chore: save description in json and html formats

* refactor: document editor components

* chore: uncomment ui package components

* fix: without props extensions refactor

* fix: merge conflicts resolved from preview

* chore: init docker compose

* chore: pages custom error codes

* chore: add health check endpoint to the live server

* chore: update without props extensions type

* chore: better error handling

* chore: update react-hook-form versions

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 2, 2024

Warning

Rate limit exceeded

@aaryan610 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 22 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Commits

Files that changed from the base of the PR and between 8526b80 and df579ae.

Walkthrough

The changes introduce a new job in the GitHub Actions workflow for building and pushing a live Docker image based on specific conditions. Additionally, several files related to collaborative editing features in a React application are added or modified, including new services, hooks, and components to enhance real-time collaboration capabilities. Environment variables and configurations are also updated to support these new features.

Changes

File(s) Change Summary
.github/workflows/build-branch.yml Added branch_build_push_live job for conditional Docker image deployment and modified branch_build_setup to include build_live output variable.
admin/package.json Updated react-hook-form dependency version from ^7.51.0 to 7.51.5.
apiserver/plane/app/views/page/base.py Modified partial_update method to update page.description.
deploy/selfhost/docker-compose.yml, docker-compose-local.yml, docker-compose.yml Added live service with configurations and updated environment variable declarations with default values.
live/.env.example Introduced example environment variable API_BASE_URL.
live/Dockerfile.dev, live/Dockerfile.live Created Dockerfiles for development and production environments with multi-stage builds for Node.js applications.
live/package.json Defined project metadata and dependencies for the live project.
live/src/... Introduced several new files implementing collaborative editing features, including authentication, page management, and API services.
nginx/nginx.conf.template Modified routing paths for various locations and introduced a new /live/ location.
package.json Added "live" to the package list.
packages/editor/... Made multiple changes to enhance collaborative editing features, including new components, hooks, and type definitions.
setup.sh Added command to copy .env.example for the live directory.
space/package.json Updated react-hook-form dependency version from ^7.38.0 to 7.51.5.
turbo.json, web/.env.example Introduced new environment variables for live configurations.
packages/ui/package.json, packages/ui/tsup.config.ts Updated build configurations and added new dependencies for improved module support.
packages/tsconfig/base.json Streamlined the presentation of the "exclude" property in the TypeScript configuration.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GitHubActions
    participant DockerHub
    User->>GitHubActions: Trigger workflow (manual or event)
    GitHubActions->>GitHubActions: Check conditions for branch_build_push_live
    alt Conditions met
        GitHubActions->>DockerHub: Build and push live Docker image
    end
Loading

🐇
In the meadow, I hop with glee,
New features bloom, oh what a spree!
With Docker and code, we dance and play,
Collaborative dreams come out to stay.
So let's rejoice, my friends, let's cheer,
For changes bright, the future is near!
🌼


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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 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.
Early access features: disabled

We are currently testing the following features in early access:

  • Anthropic claude-3-5-sonnet for code reviews: Anthropic claims that the new Claude model has stronger code understanding and code generation capabilities than their previous models. Note: Our default code review model was also updated late last week. Please compare the quality of the reviews between the two models by toggling the early access feature.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.
  • Please join our Discord Community to provide feedback and report issues on the discussion post.

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: 2

Outside diff range, codebase verification and nitpick comments (13)
live/Dockerfile.dev (1)

1-13: Suggestions for improving the Dockerfile.

The Dockerfile looks good overall, but consider the following suggestions:

  1. Pin the base image to a specific version.

    Use a specific version of the base image for better reproducibility.

    - FROM node:18-alpine
    + FROM node:18.16.0-alpine
  2. Use COPY instead of ADD.

    COPY is preferred over ADD unless you need the extra features of ADD.

  3. Combine RUN instructions.

    Combine RUN instructions to reduce the number of layers.

    - RUN apk add --no-cache libc6-compat
    - RUN yarn global add turbo
    - RUN yarn install
    + RUN apk add --no-cache libc6-compat && \
    +     yarn global add turbo && \
    +     yarn install
  4. Use WORKDIR to switch to the /app directory.

    WORKDIR is preferred over RUN cd /app for setting the working directory.

    - RUN cd /app
    + WORKDIR /app
live/src/core/services/user.service.ts (2)

17-27: LGTM!

The code changes are approved.

Consider throwing a more specific error in the catch block. For example:

  .catch((error) => {
-   throw error;
+   throw new Error(`Failed to fetch current user: ${error.message}`);
  });

29-45: LGTM!

The code changes are approved.

Consider throwing a more specific error in the catch block. For example:

  .catch((error) => {
-   throw error?.response?.data;
+   throw new Error(`Failed to fetch user project roles: ${error?.response?.data?.message}`);
  });
live/src/core/services/api.service.ts (2)

1-46: Consider adding error handling and logging.

The file provides a complete and functional implementation of a wrapper around the axios library. However, adding error handling and logging could improve the robustness and maintainability of the code.

Here are some suggestions for adding error handling and logging:

  • Add a try-catch block around the axios method calls to catch any errors that may occur.
  • Log the errors using a logging library such as winston or bunyan.
  • Add a finally block to log the completion of the request regardless of whether an error occurred or not.

For example:

import axios, { AxiosInstance } from "axios";
import { config } from "dotenv";
import { createLogger } from "winston";

config();

const logger = createLogger({
  // Configure the logger
});

export const API_BASE_URL = process.env.API_BASE_URL ?? "";

export abstract class APIService {
  // ...

  async get(url: string, params = {}, config = {}) {
    try {
      const response = await this.axiosInstance.get(url, {
        ...params,
        ...config,
      });
      return response;
    } catch (error) {
      logger.error(`Error making GET request to ${url}:`, error);
      throw error;
    } finally {
      logger.info(`Completed GET request to ${url}`);
    }
  }

  // ...
}

This is just one example, and the actual implementation may vary based on your specific requirements and preferences. The key is to add error handling and logging in a way that makes sense for your application and helps you identify and fix issues more easily.


1-46: Consider adding input validation and sanitization.

The file does not contain any sensitive information, which is good for security. However, the lack of input validation or sanitization on the url, params, data, and config parameters passed to the methods could potentially allow for injection attacks if the parameters are not properly validated or sanitized before being passed to the methods.

Here are some suggestions for adding input validation and sanitization:

  • Validate the url parameter to ensure it is a valid URL and does not contain any malicious characters.
  • Sanitize the params, data, and config parameters to remove any potential injection attacks.
  • Use a library such as validator or joi to validate and sanitize the parameters.

For example:

import axios, { AxiosInstance } from "axios";
import { config } from "dotenv";
import validator from "validator";

config();

export const API_BASE_URL = process.env.API_BASE_URL ?? "";

export abstract class APIService {
  // ...

  async get(url: string, params = {}, config = {}) {
    if (!validator.isURL(url)) {
      throw new Error(`Invalid URL: ${url}`);
    }

    const sanitizedParams = validator.sanitize(params);
    const sanitizedConfig = validator.sanitize(config);

    try {
      const response = await this.axiosInstance.get(url, {
        ...sanitizedParams,
        ...sanitizedConfig,
      });
      return response;
    } catch (error) {
      // Handle error
    }
  }

  // ...
}

This is just one example, and the actual implementation may vary based on your specific requirements and preferences. The key is to add input validation and sanitization in a way that makes sense for your application and helps you prevent potential security vulnerabilities.

live/Dockerfile.live (3)

7-8: Optimize the usage of apk update command.

The apk update command is run multiple times in the Dockerfile, which can be inefficient and increase the image size.

Consider combining the apk update and apk add commands to optimize the image build process:

-RUN apk update
-RUN apk add --no-cache libc6-compat
+RUN apk update && apk add --no-cache libc6-compat

Also applies to: 17-18


8-8: Move the installation of libc6-compat package to the runner stage.

The libc6-compat package is installed in both the builder and installer stages, but it's only needed in the final image.

Consider moving the installation of libc6-compat package to the runner stage to optimize the image size:

-RUN apk add --no-cache libc6-compat
FROM base AS runner
WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 expressjs
RUN adduser --system --uid 1001 expressjs
USER expressjs

+RUN apk update && apk add --no-cache libc6-compat

COPY --from=installer /app .
# COPY --from=installer /app/live/node_modules ./node_modules

EXPOSE 3000

Also applies to: 18-18


23-24: Copy the yarn.lock file along with the package.json files.

The yarn.lock file is copied separately from the package.json files, which can lead to inconsistencies if they are not in sync.

Consider copying the yarn.lock file along with the package.json files:

COPY --from=builder /app/out/json/ .
-COPY --from=builder /app/out/yarn.lock ./yarn.lock
live/src/core/lib/authentication.ts (1)

52-54: Improve the error message for invalid document types.

Consider including the actual document type provided in the error message to make it more informative.

-throw Error("Authentication failed: Invalid document type provided.");
+throw Error(`Authentication failed: Invalid document type '${documentType}' provided.`);
live/src/core/services/page.service.ts (3)

11-29: Improve error handling and refactor the method.

Consider the following suggestions:

  1. Add error logging before throwing the error to help with debugging.
  2. Refactor the method to use a more descriptive variable name for the response data.

Apply this diff to implement the suggestions:

async fetchDetails(
  workspaceSlug: string,
  projectId: string, 
  pageId: string,
  cookie: string
): Promise<TPage> {
  return this.get(
    `/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/`,
    {
      headers: {
        Cookie: cookie,
      },
    }
  )
-   .then((response) => response?.data)
+   .then((response) => {
+     const pageDetails = response?.data;
+     return pageDetails;
+   })
    .catch((error) => {
+     console.error('Error fetching page details:', error);
      throw error?.response?.data;
    });
}

31-51: Improve error handling and refactor the method.

Consider the following suggestions:

  1. Add error logging before throwing the error to help with debugging.
  2. Refactor the method to use a more descriptive variable name for the response data.

Apply this diff to implement the suggestions:

async fetchDescriptionBinary(
  workspaceSlug: string,
  projectId: string,
  pageId: string,
  cookie: string  
): Promise<any> {
  return this.get(
    `/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/description/`,
    {
      headers: {
        "Content-Type": "application/octet-stream",
        Cookie: cookie,
      },
      responseType: "arraybuffer",
    }
  )
-   .then((response) => response?.data)
+   .then((response) => {
+     const descriptionBinary = response?.data;
+     return descriptionBinary;
+   })
    .catch((error) => {
+     console.error('Error fetching page description binary:', error);
      throw error?.response?.data;
    });
}

53-77: Improve error handling and refactor the method.

Consider the following suggestions:

  1. Add error logging before throwing the error to help with debugging.
  2. Refactor the method to use a more descriptive variable name for the response data.

Apply this diff to implement the suggestions:

async updateDescription(
  workspaceSlug: string,
  projectId: string,
  pageId: string,
  data: {
    description_binary: string;
    description_html: string;
    description: object;
  },
  cookie: string
): Promise<any> {
  return this.patch(
    `/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/description/`,
    data,
    {
      headers: {
        Cookie: cookie,
      },
    }
  )
-   .then((response) => response?.data)
+   .then((response) => {
+     const updatedDescription = response?.data;
+     return updatedDescription;
+   })
    .catch((error) => {
+     console.error('Error updating page description:', error);
      throw error;
    });
}
deploy/selfhost/docker-compose.yml (1)

81-93: LGTM! The live service is a great addition for the realtime collaboration feature.

The live service is properly configured and follows the same structure as other services in the Docker Compose file. It inherits the necessary environment variables and specifies the required dependencies on the api and web services.

A few additional considerations:

  • Ensure that the plane-live image is built and pushed to the specified Docker registry.
  • Verify that the LIVE_REPLICAS environment variable is set appropriately based on your scaling requirements.
  • Monitor the resource usage of the live service and adjust the number of replicas if needed.

Overall, the addition of the live service looks good and aligns with the realtime collaboration feature.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8526b80 and df579ae.

Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
Files selected for processing (62)
  • .github/workflows/build-branch.yml (3 hunks)
  • admin/package.json (2 hunks)
  • apiserver/plane/app/views/page/base.py (1 hunks)
  • deploy/selfhost/docker-compose.yml (3 hunks)
  • docker-compose-local.yml (1 hunks)
  • docker-compose.yml (1 hunks)
  • live/.env.example (1 hunks)
  • live/Dockerfile.dev (1 hunks)
  • live/Dockerfile.live (1 hunks)
  • live/package.json (1 hunks)
  • live/src/ce/types/common.d.ts (1 hunks)
  • live/src/core/lib/authentication.ts (1 hunks)
  • live/src/core/lib/page.ts (1 hunks)
  • live/src/core/services/api.service.ts (1 hunks)
  • live/src/core/services/page.service.ts (1 hunks)
  • live/src/core/services/user.service.ts (1 hunks)
  • live/src/core/types/common.d.ts (1 hunks)
  • live/src/ee/types/common.d.ts (1 hunks)
  • live/src/server.ts (1 hunks)
  • live/tsconfig.json (1 hunks)
  • live/tsup.config.ts (1 hunks)
  • nginx/nginx.conf.template (1 hunks)
  • package.json (1 hunks)
  • packages/editor/package.json (2 hunks)
  • packages/editor/src/ce/extensions/document-extensions.tsx (1 hunks)
  • packages/editor/src/core/components/editors/document/collaborative-editor.tsx (1 hunks)
  • packages/editor/src/core/components/editors/document/collaborative-read-only-editor.tsx (1 hunks)
  • packages/editor/src/core/components/editors/document/index.ts (1 hunks)
  • packages/editor/src/core/components/editors/document/read-only-editor.tsx (3 hunks)
  • packages/editor/src/core/extensions/code/without-props.tsx (1 hunks)
  • packages/editor/src/core/extensions/core-without-props.ts (4 hunks)
  • packages/editor/src/core/extensions/custom-link/extension.tsx (1 hunks)
  • packages/editor/src/core/extensions/index.ts (1 hunks)
  • packages/editor/src/core/extensions/mentions/extension.tsx (1 hunks)
  • packages/editor/src/core/extensions/mentions/mentions-without-props.tsx (2 hunks)
  • packages/editor/src/core/hooks/use-collaborative-editor.ts (1 hunks)
  • packages/editor/src/core/hooks/use-editor.ts (5 hunks)
  • packages/editor/src/core/hooks/use-read-only-collaborative-editor.ts (1 hunks)
  • packages/editor/src/core/hooks/use-read-only-editor.ts (1 hunks)
  • packages/editor/src/core/types/collaboration.ts (1 hunks)
  • packages/editor/src/core/types/editor.ts (4 hunks)
  • packages/editor/src/core/types/index.ts (1 hunks)
  • packages/editor/src/index.ts (2 hunks)
  • packages/editor/src/lib.ts (1 hunks)
  • packages/editor/tsup.config.ts (1 hunks)
  • packages/tsconfig/base.json (1 hunks)
  • packages/ui/package.json (3 hunks)
  • packages/ui/tsup.config.ts (1 hunks)
  • setup.sh (1 hunks)
  • space/package.json (2 hunks)
  • turbo.json (1 hunks)
  • web/.env.example (1 hunks)
  • web/Dockerfile.web (2 hunks)
  • web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (4 hunks)
  • web/core/components/pages/editor/editor-body.tsx (6 hunks)
  • web/core/components/pages/editor/header/extra-options.tsx (4 hunks)
  • web/core/components/pages/editor/header/mobile-root.tsx (2 hunks)
  • web/core/components/pages/editor/header/options-dropdown.tsx (3 hunks)
  • web/core/components/pages/editor/header/root.tsx (2 hunks)
  • web/core/components/pages/editor/page-root.tsx (5 hunks)
  • web/core/hooks/use-online-status.ts (1 hunks)
  • web/helpers/common.helper.ts (1 hunks)
Files skipped from review due to trivial changes (9)
  • admin/package.json
  • live/.env.example
  • live/src/ee/types/common.d.ts
  • live/tsconfig.json
  • packages/editor/src/ce/extensions/document-extensions.tsx
  • packages/editor/src/core/extensions/index.ts
  • packages/editor/src/core/extensions/mentions/extension.tsx
  • packages/editor/src/lib.ts
  • packages/tsconfig/base.json
Additional context used
Biome
live/src/ce/types/common.d.ts

[error] 2-2: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

live/src/server.ts

[error] 66-79: Promise executor functions should not be async.

(lint/suspicious/noAsyncPromiseExecutor)


[error] 95-103: Promise executor functions should not be async.

(lint/suspicious/noAsyncPromiseExecutor)

actionlint
.github/workflows/build-branch.yml

312-312: shellcheck reported issue in this script: SC2086:info:8:27: Double quote to prevent globbing and word splitting

(shellcheck)

Additional comments not posted (129)
live/src/core/types/common.d.ts (2)

3-3: LGTM!

The type alias declaration is correctly implemented and exported.


1-1: Verify the existence of the imported file and type.

Ensure that the file @/plane-live/types/common.js exists and exports the type TAdditionalDocumentTypes.

Run the following script to verify the import:

packages/editor/src/core/components/editors/document/index.ts (2)

1-1: Verify the usage of the exported entities from the ./collaborative-editor module.

Ensure that all usages of the entities previously exported from the ./editor module have been updated to use the entities exported from the ./collaborative-editor module.

Run the following script to verify the usage:


2-2: Verify the usage of the exported entities from the ./collaborative-read-only-editor module.

Ensure that all usages of the entities previously exported from the ./editor module have been updated to use the entities exported from the ./collaborative-read-only-editor module where applicable.

Run the following script to verify the usage:

web/.env.example (2)

9-9: LGTM!

The addition of the NEXT_PUBLIC_LIVE_BASE_URL environment variable is approved. It follows the naming convention and is likely used for routing or API endpoint purposes in the live environment.


10-10: LGTM!

The addition of the NEXT_PUBLIC_LIVE_BASE_PATH environment variable is approved. It follows the naming convention and the "/live" value is consistent with the purpose of the variable, indicating the base path for the live environment.

packages/editor/tsup.config.ts (2)

4-4: LGTM!

The addition of the new entry point src/lib.ts to the entry array is approved. This change expands the scope of the build process to include additional source files, potentially allowing for more comprehensive module exports or functionalities.


7-7: LGTM!

The modification of the clean option from false to true is approved. This adjustment ensures that the build process will clean the output directory before each build, preventing issues related to stale files and ensuring that the build output is consistent and up-to-date.

packages/ui/tsup.config.ts (1)

1-11: LGTM!

The tsup configuration looks good:

  • The entry point is set to src/index.ts, which is a common convention.
  • The output formats are set to cjs and esm, which is a good practice for supporting both CommonJS and ES modules.
  • The dts option is set to true, which will generate TypeScript declaration files.
  • The clean option is set to false, which means that the output directory will not be cleaned before each build.
  • The external option is set to ["react"], which means that the react module will be treated as an external dependency and not bundled.
  • The injectStyle option is set to true, which will inject the styles into the JavaScript bundle.
  • The ...options spread operator merges any additional options passed to the defineConfig function.

The code changes are approved.

live/tsup.config.ts (1)

1-11: LGTM!

The tsup configuration file looks good:

  • The file structure and syntax are correct.
  • The entry point is properly specified.
  • The format array includes both cjs and esm for compatibility.
  • Generating declaration files (dts) is enabled, which is beneficial for type checking and IDE support.
  • The clean option is set to false, which may be intentional to preserve certain files.
  • react is correctly specified as an external dependency.
  • The injectStyle option is enabled, which can be useful for certain scenarios.
  • The options object is spread to allow for additional customization.

Overall, the configuration file is well-structured and follows the expected format for tsup.

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

2-2: LGTM!

The new export statement is syntactically correct and consistent with the other export statements in the file.

Please verify that the collaboration module exports the necessary entities for the Realtime Pages feature.

Run the following script to verify the exports:

Verification successful

Verification Successful: Collaboration Module Exports

The collaboration.ts module exists and exports the necessary types for the Realtime Pages feature using export type. The types defined in the module align with the expected functionality for collaboration features. No issues were found with the export statements.

  • The module exports types such as TServerHandler, TCollaborativeEditorHookProps, TCollaborativeEditorProps, and TReadOnlyCollaborativeEditorProps.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the exports of the `collaboration` module.

# Test: Search for the `collaboration` module. Expect: The module exists.
fd --type file --regex '.*collaboration\.ts$' --exec cat

# Test: Search for the exports of the `collaboration` module. Expect: The module exports the necessary entities for the Realtime Pages feature.
fd --type file --regex '.*collaboration\.ts$' --exec rg --multiline --multiline-dotall $'export\s+\{[\s\S]*\}'

Length of output: 1511

setup.sh (1)

12-12: LGTM!

The code change is approved. It correctly sets up the environment file for the live directory, following the same pattern as the other setup commands. This change is necessary to include the live environment in the setup process, as indicated by the AI-generated summary.

web/core/hooks/use-online-status.ts (1)

1-22: LGTM!

The useOnlineStatus hook is well-implemented and follows the recommended patterns for custom hooks in React. Here are the key points:

  • The hook properly manages the isOnline state using the useState hook, initializing it with the value of navigator.onLine if available, otherwise defaulting to true.
  • The updateOnlineStatus function correctly updates the isOnline state based on the current value of navigator.onLine.
  • The useEffect hook is used appropriately to add and remove event listeners for the online and offline events, ensuring there are no memory leaks.
  • The hook returns an object with a clear and concise property name, making it easy to use in the consuming component.

Overall, the code is clean, readable, and follows best practices for custom hooks in React.

package.json (1)

10-10: LGTM!

The addition of the "live" entry to the workspaces array is consistent with the PR summary and the list of alterations. It suggests that a new package or module has been added to the project to support the Realtime Pages feature.

The code change is approved.

packages/editor/src/index.ts (2)

10-11: Approve the new exports for collaborative editing.

The changes align with the PR objectives of introducing collaborative editing capabilities. The addition of CollaborativeDocumentEditorWithRef and CollaborativeDocumentReadOnlyEditorWithRef exports suggests support for multiple users working simultaneously and a read-only mode for collaborative documents.

Please verify that the new exports are being used correctly throughout the codebase. Run the following script to check the usage:

Verification successful

New exports are correctly integrated into the codebase.

The exports CollaborativeDocumentEditorWithRef and CollaborativeDocumentReadOnlyEditorWithRef are being used in multiple files, confirming their integration into the collaborative editing feature.

  • CollaborativeDocumentEditorWithRef is used in:

    • web/core/components/pages/editor/editor-body.tsx
    • packages/editor/src/core/components/editors/document/collaborative-editor.tsx
  • CollaborativeDocumentReadOnlyEditorWithRef is used in:

    • web/core/components/pages/editor/editor-body.tsx
    • packages/editor/src/core/components/editors/document/collaborative-read-only-editor.tsx
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the new exports in the codebase.

# Test 1: Search for the usage of `CollaborativeDocumentEditorWithRef`. Expect: At least one occurrence.
rg --type typescript -A 5 $'CollaborativeDocumentEditorWithRef'

# Test 2: Search for the usage of `CollaborativeDocumentReadOnlyEditorWithRef`. Expect: At least one occurrence.
rg --type typescript -A 5 $'CollaborativeDocumentReadOnlyEditorWithRef'

Length of output: 203


Script:

#!/bin/bash
# Description: Verify the usage of the new exports in the codebase.

# Test 1: Search for the usage of `CollaborativeDocumentEditorWithRef`. Expect: At least one occurrence.
rg --type ts -A 5 $'CollaborativeDocumentEditorWithRef'

# Test 2: Search for the usage of `CollaborativeDocumentReadOnlyEditorWithRef`. Expect: At least one occurrence.
rg --type ts -A 5 $'CollaborativeDocumentReadOnlyEditorWithRef'

Length of output: 5228


Line range hint 1-40: Verify the impact of removing the @/components/editors/document/helpers export.

The export statement for helpers has been altered by removing the export of @/components/editors/document/helpers. This change could potentially impact other parts of the codebase that rely on these helpers.

Please verify that removing this export doesn't break any existing functionality. Run the following script to check for any usage of the removed export:

If the script returns any occurrences, please ensure that the removal of this export is handled appropriately to avoid breaking changes.

Verification successful

No impact from removing @/components/editors/document/helpers export.

The search did not find any usage of the removed export in the codebase, indicating that its removal does not affect any existing functionality. No further action is required.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the impact of removing the `@/components/editors/document/helpers` export.

# Test: Search for the usage of `@/components/editors/document/helpers`. Expect: No occurrences.
rg --type typescript -A 5 $'@/components/editors/document/helpers'

Length of output: 100


Script:

#!/bin/bash
# Description: Verify the impact of removing the `@/components/editors/document/helpers` export.

# Test: Search for the usage of `@/components/editors/document/helpers` in TypeScript files.
rg --glob '*.ts' --glob '*.tsx' -A 5 '@/components/editors/document/helpers'

Length of output: 76

packages/editor/src/core/extensions/mentions/mentions-without-props.tsx (2)

2-4: LGTM!

The changes to the imports are approved:

  • Including MentionOptions in the Mention import enhances the configuration options for mentions.
  • Importing IMentionHighlight from @/types enables support for dynamic highlighting options.

6-9: LGTM!

The changes to the CustomMentionOptions interface are approved:

  • Extending MentionOptions allows for inheriting the base configuration options while adding custom properties.
  • The mentionHighlights property enables dynamic highlighting of mentions.
  • The readonly property provides control over the editability of mentions.

Verify that the new properties are being used correctly in the codebase:

Verification successful

Properties Verified and Used Correctly

The mentionHighlights and readonly properties in the CustomMentionOptions interface are being used correctly across the codebase. They are integrated into various components and extensions, fulfilling their intended roles in handling mentions and controlling editability.

  • mentionHighlights is used in files such as:

    • space/core/store/mentions.store.ts
    • space/core/components/editor/rich-text-read-only-editor.tsx
    • web/core/components/editor/rich-text-editor/rich-text-editor.tsx
  • readonly is used in files such as:

    • packages/editor/src/core/extensions/read-only-extensions.tsx
    • packages/editor/src/core/extensions/extensions.tsx
    • packages/editor/src/core/extensions/mentions/mention-node-view.tsx
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the new properties in `CustomMentionOptions`.

# Test 1: Search for the usage of `mentionHighlights`. Expect: At least one occurrence.
rg --type typescript -A 5 $'mentionHighlights'

# Test 2: Search for the usage of `readonly`. Expect: At least one occurrence.
rg --type typescript -A 5 $'readonly'

Length of output: 152


Script:

#!/bin/bash
# Description: Verify the usage of the new properties in `CustomMentionOptions`.

# Test 1: Search for the usage of `mentionHighlights`. Expect: At least one occurrence.
rg --glob '*.ts' --glob '*.tsx' -A 5 'mentionHighlights'

# Test 2: Search for the usage of `readonly`. Expect: At least one occurrence.
rg --glob '*.ts' --glob '*.tsx' -A 5 'readonly'

Length of output: 27121

live/src/core/services/user.service.ts (1)

11-15: LGTM!

The code changes are approved.

live/src/core/services/api.service.ts (3)

1-7: LGTM!

The code segment is correctly importing the required dependencies, loading the environment variables, and defining the API_BASE_URL constant.


8-18: LGTM!

The abstract class APIService is correctly defined with a constructor that initializes the required properties and creates an instance of axios with the provided baseURL and withCredentials set to true.


20-45: LGTM!

The methods for making HTTP requests are correctly defined and cover all the common HTTP methods. The methods correctly pass the provided parameters to the corresponding axios method.

live/package.json (5)

1-15: LGTM!

The package metadata looks good. The choice of package name, version, and main entry point seem appropriate.


8-12: LGTM!

The scripts look good. They cover the essential build, start, and dev workflows. The "dev" script is particularly useful for development as it watches for changes and restarts the server automatically.


16-33: LGTM!

The dependencies look appropriate for a real-time collaborative editing feature. Hocuspocus and y-prosemirror are well-suited for this use case. The other dependencies are also commonly used in Node.js projects.


34-43: LGTM!

The devDependencies look appropriate for a TypeScript project. They include the necessary type definitions and tools for development and building.


1-44: LGTM!

The package.json file looks good overall. It follows best practices and includes everything necessary for the project.

web/helpers/common.helper.ts (1)

12-14: LGTM!

The code changes are approved for the following reasons:

  • The new exported constants LIVE_BASE_PATH and LIVE_URL are correctly initialized using the environment variables NEXT_PUBLIC_LIVE_BASE_PATH and NEXT_PUBLIC_LIVE_BASE_URL.
  • The changes extend the module's capabilities to accommodate live environment settings, which may be crucial for routing or API calls in the application.
  • The code changes are consistent with the AI-generated summary.
turbo.json (1)

11-11: LGTM!

The addition of NEXT_PUBLIC_LIVE_BASE_URL to the globalEnv array is consistent with the existing configuration and follows the naming convention for public environment variables in a Next.js application.

live/Dockerfile.live (1)

42-42: Verify if the commented out COPY command for node_modules is needed.

The COPY --from=installer /app/live/node_modules ./node_modules line is commented out, which may cause issues if the application relies on it.

Please verify if the node_modules directory needs to be copied from the installer stage to the runner stage. If it's not needed, consider removing the commented out line to avoid confusion.

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

17-20: LGTM!

The code changes are approved.


22-36: LGTM!

The code changes are approved.


38-44: LGTM!

The code changes are approved.


46-48: LGTM!

The code changes are approved.

space/package.json (2)

43-43: Verify the reason for using an exact version instead of a caret range.

The version of react-hook-form has been changed from a caret range (^7.38.0) to an exact version (7.51.5). While this change ensures that the exact specified version will be installed, it might cause the project to miss out on future bug fixes and improvements in the dependency.

It's generally recommended to use a caret range (e.g., ^7.51.5) to automatically get non-breaking updates. This allows the project to benefit from bug fixes and performance improvements without requiring manual updates.

Please verify the reason for using an exact version instead of a caret range. If there's no specific reason, consider updating the version to use a caret range.


43-43: Ensure the application is thoroughly tested with the new version of react-hook-form.

Updating the dependency version might introduce breaking changes that could affect the application. It's crucial to thoroughly test the application to ensure compatibility with the new version of react-hook-form.

Please confirm that the application has been tested with the new version of react-hook-form and no issues were found. If testing has not been performed yet, consider creating a task to prioritize testing the application with the updated dependency.

live/src/core/lib/authentication.ts (4)

1-14: LGTM!

The imports and type definitions are correctly defined.


16-34: LGTM!

The handleAuthentication function correctly handles the props, fetches the current user info, and validates the token.


36-51: LGTM!

The conditional block for project_page document type correctly validates the required parameters, fetches the user's role, and sets the connection to read-only for roles lower than a member.


56-62: LGTM!

The return statement correctly returns the authenticated user object with the required properties.

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

10-69: LGTM!

The useReadOnlyCollaborativeEditor hook is well-structured and follows best practices:

  • The hook uses useMemo to memoize the HocuspocusProvider instance.
  • The hook uses useEffect to clean up the provider on unmount.
  • The hook uses useLayoutEffect to set up IndexeddbPersistence for offline support.
  • The hook uses the useReadOnlyEditor hook to create the editor instance, which is a good example of composition.
  • The hook returns the editor instance and a boolean flag, which is a good example of a clear and concise API.

The code changes are approved.

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

39-39: LGTM!

The code changes are approved.


42-50: LGTM!

The code changes are approved.


53-53: LGTM!

The code changes are approved.


64-65: LGTM!

The code changes are approved.


21-21: Verify the impact of changing the type of embedHandler to any.

The type of the embedHandler property in the IDocumentReadOnlyEditor interface has been changed from TEmbedConfig to any. This change broadens the accepted type and may impact type safety.

Run the following script to verify the usage of embedHandler:

packages/ui/package.json (4)

9-9: LGTM!

The addition of the "type": "module" declaration is a valid change that aligns with the modernization of the package configuration. It indicates that the package is intended to be used as an ECMAScript module, which can provide benefits such as improved module resolution and support for modern import/export syntax.


16-17: LGTM!

The simplification of the build and development scripts is a valid change that can enhance maintainability and align with a more standardized setup. By removing specific flags and relying on default configurations, the build process becomes more streamlined and easier to manage.

Please ensure that the necessary configurations are properly set within tsup to maintain the desired build behavior. You can verify this by running the build script and checking the generated output.


53-53: LGTM!

The addition of the @types/lodash package as a dependency is a valid change that can improve the development experience and type safety when using Lodash in TypeScript projects. By providing type definitions, it enables better code completion, type checking, and catches potential type-related issues at compile-time.


68-68: LGTM!

Updating the tsup package to a newer version is generally a good practice to take advantage of bug fixes, performance improvements, and new features.

Please review the changelog or release notes of the tsup package to understand the changes between versions ^5.10.1 and ^7.2.0. Ensure that the updated version is compatible with the project's requirements and doesn't introduce any breaking changes.

web/core/components/pages/editor/header/mobile-root.tsx (4)

11-20: LGTM!

The changes to the Props type look good:

  • The reordering of properties improves readability and organization.
  • The new hasConnectionFailed property is a clear boolean flag to indicate the connection status.

26-35: LGTM!

The changes to the destructured props are consistent with the changes in the Props type.


58-58: LGTM!

The usage of the hasConnectionFailed prop is consistent with its addition to the Props type.


Line range hint 1-73: LGTM!

The removal of the handleSaveDescription prop usage is consistent with its removal from the destructured props. The component no longer needs to handle the save description functionality.

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

15-63: LGTM!

The CollaborativeDocumentReadOnlyEditor component is well-structured and follows best practices for functional components. It uses TypeScript to define the props interface, default values for some props, a custom hook to get the editor instance, and passes the editor instance and other props to the PageRenderer component. The component is focused on its main responsibility and separates concerns.


65-72: LGTM!

The CollaborativeDocumentReadOnlyEditorWithRef component is a simple wrapper around the CollaborativeDocumentReadOnlyEditor component that forwards refs. It uses the forwardRef higher-order component to forward refs, which is a good practice for functional components. The component also sets a display name for better debugging.

packages/editor/package.json (2)

18-22: LGTM!

The new entry in the exports field for "./lib" looks good. It improves the module's export capabilities by allowing consumers to access the library through a dedicated path, thereby enhancing modularity and usability.


38-38: LGTM!

The addition of the new dependency @hocuspocus/provider looks good. It may introduce new features or fixes related to the Hocuspocus library.

packages/editor/src/core/extensions/core-without-props.ts (3)

9-17: LGTM!

The reorganized imports improve modularity and maintainability.


Line range hint 19-78: LGTM!

The changes to the CoreEditorExtensionsWithoutProps export simplify the structure and reflect a shift in functionality. The removed extensions and the addition of CustomCodeBlockExtensionWithoutProps suggest a refactoring aimed at streamlining the editor's capabilities.


86-86: LGTM!

The new export DocumentEditorExtensionsWithoutProps expands the functionality for document editing by including the IssueWidgetWithoutProps extension.

packages/editor/src/core/components/editors/document/collaborative-editor.tsx (5)

1-13: LGTM!

The import statements are well-organized and follow a consistent pattern. There are no unused imports or missing dependencies based on the usage in the file.


15-80: LGTM!

The CollaborativeDocumentEditor component is well-structured and follows best practices:

  • The destructuring of props and setting default values improves readability.
  • The conditional addition of the IssueWidget extension based on the embedHandler prop is a good practice.
  • The usage of the useCollaborativeEditor hook encapsulates the editor initialization logic.
  • The rendering of the PageRenderer component with the editor and other props is straightforward.

82-86: LGTM!

The CollaborativeDocumentEditorWithRef component is a simple wrapper that forwards the ref to the CollaborativeDocumentEditor component. This is a common pattern used in React to expose the ref of an inner component to the parent component. The usage of React.forwardRef is correct, and the prop spreading is a concise way to pass the props to the inner component.


88-88: LGTM!

Assigning a displayName to the component is a good practice for debugging and testing purposes. It makes the component name appear in the React DevTools and error messages, making it easier to identify the component. The assigned name is descriptive and matches the component name.


90-90: LGTM!

The export statement is correctly placed at the end of the file and exports the CollaborativeDocumentEditorWithRef component, which is the main component defined in this file. The export is a named export, which allows importing the component with a specific name.

nginx/nginx.conf.template (4)

31-36: LGTM!

The changes to the /api/ location and its corresponding proxy_pass directive are approved. They align with the overall API structure improvements mentioned in the PR summary.


39-44: LGTM!

The changes to the /auth/ location and its corresponding proxy_pass directive are approved. They align with the overall API structure improvements mentioned in the PR summary.


47-53: LGTM!

The changes to the /god-mode/ location and its corresponding proxy_pass directive are approved. They align with the overall API structure improvements mentioned in the PR summary.


55-60: Verify the purpose and functionality of the new /live/ endpoint.

The new /live/ location and its corresponding proxy_pass directive seem to be related to the Realtime Pages feature mentioned in the PR summary. Please provide more information on how this endpoint will be used and what specific functionalities it enables for the Realtime Pages feature.

web/core/components/pages/editor/header/root.tsx (3)

13-13: LGTM!

The changes to the Props type are approved:

  • The addition of editorReady and hasConnectionFailed properties will help the component manage the editor's readiness state and connection status.
  • The reordering of properties doesn't affect the functionality.

Also applies to: 16-16, 20-22


28-28: LGTM!

The changes to the destructuring of props are approved:

  • The destructuring of editorReady and hasConnectionFailed is necessary to use these properties within the component.
  • The reordering of destructured properties doesn't affect the functionality.

Also applies to: 30-31, 33-34, 36-36


68-68: Verify the removal of handleSaveDescription prop.

Ensure that the removal of handleSaveDescription prop from the PageExtraOptions component doesn't break any existing functionality.

Run the following script to verify the usage of handleSaveDescription:

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

1-12: LGTM!

The imports are relevant and there are no unused imports. The custom imports are from the expected locations within the project.


13-30: LGTM!

The hook definition and the destructured props look good. The prop types are defined in TCollaborativeEditorProps.


32-56: LGTM!

The initialization and destruction of the Hocuspocus provider look good:

  • The configuration options are set based on the props passed to the hook.
  • Using the user ID as the token is a good way to verify the user on the server.
  • Destroying and disconnecting the provider on unmount ensures proper cleanup.

58-94: LGTM!

The IndexedDB integration and the useEditor hook look good:

  • The IndexedDB integration provides offline support.
  • The useEditor hook is configured with relevant options and extensions.
  • The Collaboration extension is correctly configured with the Hocuspocus provider's document.
  • The other extensions also seem relevant to the collaborative editor functionality.
packages/editor/src/core/hooks/use-read-only-editor.ts (1)

15-15: LGTM!

The code change is approved for the following reasons:

  • The change allows for greater flexibility in the usage of the CustomReadOnlyEditorProps interface, enabling instances of this interface to be created without necessarily providing an initialValue.
  • The change is consistent with the rest of the code in the file. For example, the useReadOnlyEditor function checks if the initialValue is a string before setting the editor content.
web/Dockerfile.web (2)

42-46: LGTM!

The code changes are approved.


86-90: LGTM!

The code changes are approved.

docker-compose.yml (1)

102-110: LGTM!

The new live service configuration looks good. It follows the same structure as other services in the file and has all the necessary properties defined.

packages/editor/src/core/types/editor.ts (4)

4-14: LGTM!

The addition of new types in the import statements aligns with the goal of enhancing the editor's collaborative features and AI integrations.


67-77: LGTM!

The ICollaborativeDocumentEditor interface introduces properties that enhance the editor's collaborative features and user management, which aligns with the PR objectives.


96-103: LGTM!

The ICollaborativeDocumentReadOnlyEditor interface introduces properties that maintain collaborative functionalities in read-only contexts, which aligns with the PR objectives.


110-121: LGTM!

The TUserDetails and TRealtimeConfig types introduce structures for managing user-specific settings and real-time interactions, which aligns with the PR objectives.

docker-compose-local.yml (1)

89-102: LGTM!

The new live service configuration looks good:

  • It follows the same structure as other services in the file.
  • It is built from a separate Dockerfile, allowing for independent development and testing.
  • It is connected to the same network as other services, enabling communication between them.
  • The volume mount allows for local development and testing of the live service.
  • The dependencies ensure that the required services are started before live.
packages/editor/src/core/extensions/code/without-props.tsx (3)

13-32: LGTM!

The Tab keyboard shortcut handler is correctly implemented. It inserts a tab character at the current cursor position if the selection is empty and the cursor is inside a code block. The error handling using try-catch is also good.


33-67: LGTM!

The ArrowUp keyboard shortcut handler is correctly implemented. It moves the cursor to a new paragraph at the start of the document if the cursor is at the start of the first code block in the document. The error handling using try-catch is also good.


68-108: LGTM!

The ArrowDown keyboard shortcut handler is correctly implemented. It moves the cursor to the next node after the code block if the cursor is at the end of the code block and exitOnArrowDown option is enabled. The error handling using try-catch is also good.

live/src/server.ts (4)

18-45: LGTM!

The code segment correctly sets up the authentication logic for the Hocuspocus server. The onAuthenticate callback extracts the necessary data from the request and invokes the handleAuthentication function to handle the authentication process. The code segment also handles the error cases appropriately.


46-107: LGTM!

The code segment correctly sets up the extensions for the Hocuspocus server. The Redis and Logger extensions are configured appropriately. The Database extension's fetch and store callbacks handle the document retrieval and update logic based on the document type.

Tools
Biome

[error] 66-79: Promise executor functions should not be async.

(lint/suspicious/noAsyncPromiseExecutor)


[error] 95-103: Promise executor functions should not be async.

(lint/suspicious/noAsyncPromiseExecutor)


109-119: LGTM!

The code segment correctly sets up an Express server with WebSocket support using the express-ws library. The server listens for WebSocket connections on the /collaboration endpoint and handles them using the handleConnection method of the Hocuspocus server.


121-123: LGTM!

The code segment correctly starts the Express server and listens on the specified port. The server logs a message when it starts listening, which is helpful for debugging and monitoring purposes.

web/core/components/pages/editor/header/extra-options.tsx (6)

5-5: LGTM!

The code changes are approved.


9-9: LGTM!

The code changes are approved.


18-18: LGTM!

The code changes are approved.


25-25: LGTM!

The code changes are approved.


31-31: LGTM!

The code changes are approved.


51-76: LGTM!

The code changes are approved.

live/src/core/lib/page.ts (3)

23-69: LGTM!

The updatePageDescription function is well-implemented and follows a clear flow. It performs the necessary transformations and updates the page description using the pageService. The error handling ensures that any errors are caught and logged.


71-107: LGTM!

The fetchDescriptionHTMLAndTransform function is well-implemented and performs the necessary transformations to convert the existing HTML description to Uint8Array format. It uses the appropriate functions and extensions to achieve this. The error handling ensures that any errors are caught and logged.


109-144: LGTM!

The fetchPageDescriptionBinary function is well-implemented and fetches the binary description data. It handles the case when the data is empty by fetching and transforming the HTML description. It uses the appropriate service methods and functions to achieve this. The error handling ensures that any errors are caught and logged.

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

33-33: LGTM!

The code changes are approved.


88-91: LGTM!

The code changes are approved.


115-115: LGTM!

The code changes are approved.


125-125: LGTM!

The code changes are approved.


135-135: LGTM!

The code changes are approved.

deploy/selfhost/docker-compose.yml (3)

6-6: LGTM!

Setting a default value for the SENTRY_DSN environment variable is a good practice to handle cases where the variable is not explicitly set. An empty string is an appropriate default value for the Sentry DSN.


8-8: Verify the CORS configuration.

Setting a default value for the CORS_ALLOWED_ORIGINS environment variable is a good practice. However, please ensure that the empty default value aligns with your intended CORS configuration. If CORS should be enabled by default, consider setting an appropriate default value.


37-38: Verify the API base URL.

The new API_BASE_URL environment variable is being introduced with a default value of http://api:8000. Please ensure that this default value correctly points to the api service within the Docker Compose network.

packages/editor/src/core/extensions/custom-link/extension.tsx (1)

139-141: LGTM!

The code changes are approved. The updated condition simplifies the check and potentially improves the handling of valid HTMLElement nodes.

web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/pages/(detail)/header.tsx (4)

5-5: LGTM!

The code segment is approved.


10-10: LGTM!

The code segment is approved.


35-35: LGTM!

The code segment is approved.


37-37: LGTM!

The code segment is approved.

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

6-7: LGTM!

The new imports are necessary for the collaborative editing functionality.

Also applies to: 13-14


21-22: LGTM!

The new imports are correctly used in the component.


40-42: LGTM!

The new properties are correctly used in the component.

Also applies to: 45-45


103-108: LGTM!

The new callbacks and objects are correctly used in the component to enable real-time collaboration.

Also applies to: 110-116, 122-132


Line range hint 168-194: LGTM!

The CollaborativeDocumentEditorWithRef component is correctly configured with the new props to enable real-time collaboration.


Line range hint 201-222: LGTM!

The CollaborativeDocumentReadOnlyEditorWithRef component is correctly configured with the new props to enable real-time collaboration.

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

58-61: LGTM!

The code changes that consolidate state and ref declarations are approved. This improves readability and maintainability.

.github/workflows/build-branch.yml (6)

30-30: LGTM!

The new output reference build_live is correctly added to the branch_build_setup job. This allows the branch_build_push_live job to conditionally run based on whether the live files have changed.


83-89: LGTM!

The new file change detection section live is correctly added. This allows the workflow to detect changes in the live directory and its dependencies (packages/, package.json, yarn.lock, tsconfig.json, turbo.json), and trigger the live build accordingly.


299-302: LGTM!

The new job branch_build_push_live is correctly added to build and push the live server Docker image. The job is appropriately conditioned to run based on the value of build_live, manual dispatch, release event, or if the branch is master. It runs on an Ubuntu 20.04 environment and correctly depends on the branch_build_setup job.


303-309: LGTM!

The environment variables LIVE_TAG, TARGET_BRANCH, BUILDX_DRIVER, BUILDX_VERSION, BUILDX_PLATFORMS, and BUILDX_ENDPOINT are correctly defined for the branch_build_push_live job. Their values are appropriately set based on the outputs of the branch_build_setup job, ensuring that the correct configurations are used for building and pushing the live server Docker image.


310-350: LGTM!

The steps in the branch_build_push_live job are correctly implemented:

  1. Setting the live Docker tag based on the event type (release, master branch, or custom tag).
  2. Logging into Docker Hub using the provided secrets.
  3. Setting up Docker Buildx using the configurations from the environment variables.
  4. Checking out the repository.
  5. Building and pushing the live server Docker image to Docker Hub using the specified Dockerfile and tags.

The steps follow the necessary flow to build and push the live server Docker image to Docker Hub with the appropriate configurations.

Tools
actionlint

312-312: shellcheck reported issue in this script: SC2086:info:8:27: Double quote to prevent globbing and word splitting

(shellcheck)


312-312: Skipped: False positive from actionlint.

The shellcheck issue reported by actionlint at line 312 is a false positive. The script is correctly using single brackets for string comparison and there are no variables or expressions that require double quoting.

Tools
actionlint

312-312: shellcheck reported issue in this script: SC2086:info:8:27: Double quote to prevent globbing and word splitting

(shellcheck)

apiserver/plane/app/views/page/base.py (1)

569-569: LGTM!

The code change is approved.

Comment on lines +1 to +2
// eslint-disable-next-line @typescript-eslint/ban-types
export type TAdditionalDocumentTypes = {} No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

Define TAdditionalDocumentTypes with explicit properties instead of using {}.

The empty object type {} means "any non-nullable value" in TypeScript, which defeats the purpose of type checking and can lead to errors.

Define the type with explicit properties and their types based on the expected additional document types. For example:

export type TAdditionalDocumentTypes = {
  // Define properties and their types here
  // Example:
  // customDoc: {
  //   id: string;
  //   name: string;
  //   // ...
  // };
};

If there are no additional document types expected at the moment, consider removing the type declaration altogether until it is needed.

Let me know if you need help defining the properties and their types for TAdditionalDocumentTypes. I can assist you in updating the type definition based on the expected additional document types in your application.

Tools
Biome

[error] 2-2: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

Comment on lines +66 to +79
return new Promise(async (resolve) => {
try {
if (documentType === "project_page") {
const fetchedData = await fetchPageDescriptionBinary(
params,
pageId,
cookie,
);
resolve(fetchedData);
}
} catch (error) {
console.error("Error in fetching document", error);
}
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove async from Promise executor functions.

The static analysis tool correctly points out that the Promise executor functions should not be async. Using async in the executor function can lead to unintended behavior and potential bugs.

Apply this diff to fix the issue:

-return new Promise(async (resolve) => {
+return new Promise((resolve) => {
   try {
     if (documentType === "project_page") {
       const fetchedData = await fetchPageDescriptionBinary(
-return new Promise(async () => {
+return new Promise(() => {
   try {
     if (documentType === "project_page") {
       await updatePageDescription(params, pageId, state, cookie);

Also applies to: 95-103

Tools
Biome

[error] 66-79: Promise executor functions should not be async.

(lint/suspicious/noAsyncPromiseExecutor)

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.

3 participants