Skip to content

feat: add rich text description to modules - #9502

Open
Syed-Ali-Abbas-Zaidi wants to merge 2 commits into
makeplane:previewfrom
Syed-Ali-Abbas-Zaidi:feat/git-280-module-rich-description
Open

feat: add rich text description to modules#9502
Syed-Ali-Abbas-Zaidi wants to merge 2 commits into
makeplane:previewfrom
Syed-Ali-Abbas-Zaidi:feat/git-280-module-rich-description

Conversation

@Syed-Ali-Abbas-Zaidi

@Syed-Ali-Abbas-Zaidi Syed-Ali-Abbas-Zaidi commented Jul 29, 2026

Copy link
Copy Markdown

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Test Scenarios

References

Summary by CodeRabbit

  • New Features
    • Added rich-text module description editing with support for mentions and asset uploads, including image handling.
    • Enabled inline editing of module descriptions directly from the analytics sidebar.
    • Module forms now use the rich-text description editor and automatically initialize from existing plain-text descriptions.
  • Bug Fixes
    • Improved rich-text initialization so empty content doesn’t render a blank editor.
    • Added clearer saving-state feedback while description changes are being submitted.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e7fae07-87ab-46c2-80e7-6b8cea8a90bf

📥 Commits

Reviewing files that changed from the base of the PR and between aaab462 and 335f675.

📒 Files selected for processing (4)
  • apps/api/plane/db/models/asset.py
  • apps/web/core/components/modules/analytics-sidebar/root.tsx
  • apps/web/core/components/modules/description-editor.tsx
  • packages/utils/src/module.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/api/plane/db/models/asset.py
  • packages/utils/src/module.ts
  • apps/web/core/components/modules/analytics-sidebar/root.tsx
  • apps/web/core/components/modules/description-editor.tsx

📝 Walkthrough

Walkthrough

Module descriptions now support rich-text HTML editing, legacy text migration, workspace mentions, and editor asset operations across module forms and the analytics sidebar. New module description asset types and backend asset routing are included.

Changes

Module rich-text description editing

Layer / File(s) Summary
Description contract and legacy conversion
apps/api/plane/db/models/asset.py, packages/types/src/enums.ts, packages/utils/src/module.ts
Adds the module description asset type and routing, and converts legacy plain-text descriptions into escaped HTML initial values.
Rich-text editor component
apps/web/core/components/modules/description-editor.tsx
Adds ModuleDescriptionEditor with form binding, mentions, file uploads, and asset duplication.
Module form integration
apps/web/core/components/modules/form.tsx
Uses description_html defaults, reset synchronization, and the rich-text editor in the module form.
Analytics sidebar editing
apps/web/core/components/modules/analytics-sidebar/root.tsx
Replaces read-only description rendering with editable content and submission-status handling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ModuleForm
  participant ModuleDescriptionEditor
  participant RichTextEditor
  participant WorkspaceService
  participant ModuleUpdate
  ModuleForm->>ModuleDescriptionEditor: provide description_html initial value
  ModuleDescriptionEditor->>RichTextEditor: bind description_html
  RichTextEditor->>WorkspaceService: searchEntity(project_id)
  RichTextEditor-->>ModuleDescriptionEditor: edited HTML
  ModuleDescriptionEditor-->>ModuleForm: update form field
  ModuleForm->>ModuleUpdate: submit description_html
Loading

Suggested reviewers: dheeru0198, sriramveeraghanta, pablohashescobar

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description only includes template headings and checkbox selections, with no actual change details, tests, screenshots, or references. Add a real description of the changes, list test scenarios run, include screenshots if relevant, and add any issue references.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding rich text descriptions to modules.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

@Syed-Ali-Abbas-Zaidi

Copy link
Copy Markdown
Author

Closes #9428

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
apps/web/core/components/modules/analytics-sidebar/root.tsx (2)

253-253: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Memoize getModuleDescriptionInitialValue(moduleDetails) for consistency and to avoid recomputation on unrelated re-renders.

Computed inline here on every observer re-render, unlike the sibling usage in form.tsx which wraps the same utility in useMemo. Since this component re-renders on any relevant mobx observable change, this recomputes the HTML emptiness check/conversion each time even when the description itself hasn't changed.

♻️ Proposed fix
+  const descriptionInitialValue = useMemo(() => getModuleDescriptionInitialValue(moduleDetails), [moduleDetails]);
...
-          initialValue={getModuleDescriptionInitialValue(moduleDetails)}
+          initialValue={descriptionInitialValue}

(Add useMemo to the existing react import.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/core/components/modules/analytics-sidebar/root.tsx` at line 253,
Memoize the value passed to `initialValue` in the component containing this prop
by adding `useMemo` to the React imports and wrapping
`getModuleDescriptionInitialValue(moduleDetails)` with dependencies limited to
the relevant module description input, matching the existing pattern in
`form.tsx`.

222-224: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid any for the status select's onChange value.

selectedStatus flows directly into submitChanges({ status: selectedStatus }), which targets IModule["status"] (TModuleStatus). Typing it explicitly avoids losing compile-time safety on this value.

As per coding guidelines, "TypeScript strict mode enabled; all files must be typed."

♻️ Proposed fix
-                  onChange={(selectedStatus: any) => {
+                  onChange={(selectedStatus: TModuleStatus) => {
                     submitChanges({ status: selectedStatus });
                   }}

(Add TModuleStatus to the @plane/types import at Line 26.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/core/components/modules/analytics-sidebar/root.tsx` around lines 222
- 224, Replace the any annotation on selectedStatus in the analytics sidebar
status select onChange handler with TModuleStatus, importing TModuleStatus from
`@plane/types`, so submitChanges receives the module status type safely.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/api/plane/db/models/asset.py`:
- Line 47: Update the asset_url resolution logic in the asset model to include
MODULE_DESCRIPTION alongside the existing description entity types, ensuring
uploaded and duplicated module-editor assets resolve to their URLs instead of
returning None.

In `@apps/web/core/components/modules/description-editor.tsx`:
- Around line 68-98: Update the uploadFile and duplicateFile error handlers to
log the caught errors with the component’s established logging mechanism before
rethrowing. Preserve the user-facing error messages, and change duplicateFile to
capture the original error and include it as the cause, matching uploadFile’s
behavior.
- Around line 46-99: Add a module-specific React key to the RichTextEditor
rendered by ModuleDescriptionEditor, using moduleId so the uncontrolled editor
remounts when the modal switches modules. Keep the existing static id and all
other editor props unchanged.

---

Nitpick comments:
In `@apps/web/core/components/modules/analytics-sidebar/root.tsx`:
- Line 253: Memoize the value passed to `initialValue` in the component
containing this prop by adding `useMemo` to the React imports and wrapping
`getModuleDescriptionInitialValue(moduleDetails)` with dependencies limited to
the relevant module description input, matching the existing pattern in
`form.tsx`.
- Around line 222-224: Replace the any annotation on selectedStatus in the
analytics sidebar status select onChange handler with TModuleStatus, importing
TModuleStatus from `@plane/types`, so submitChanges receives the module status
type safely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f3d12995-786b-4cb4-b044-3c2512bfe4f4

📥 Commits

Reviewing files that changed from the base of the PR and between 15e8357 and 438e6ae.

📒 Files selected for processing (6)
  • apps/api/plane/db/models/asset.py
  • apps/web/core/components/modules/analytics-sidebar/root.tsx
  • apps/web/core/components/modules/description-editor.tsx
  • apps/web/core/components/modules/form.tsx
  • packages/types/src/enums.ts
  • packages/utils/src/module.ts

Comment thread apps/api/plane/db/models/asset.py
Comment thread apps/web/core/components/modules/description-editor.tsx
Comment thread apps/web/core/components/modules/description-editor.tsx
@Syed-Ali-Abbas-Zaidi
Syed-Ali-Abbas-Zaidi force-pushed the feat/git-280-module-rich-description branch from aaab462 to 335f675 Compare July 29, 2026 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant