Skip to content

fixed: Links in note preview not visible #16043#16267

Merged
charlesBochet merged 4 commits intotwentyhq:mainfrom
piyush-rj:fix-issue-16043
Dec 3, 2025
Merged

fixed: Links in note preview not visible #16043#16267
charlesBochet merged 4 commits intotwentyhq:mainfrom
piyush-rj:fix-issue-16043

Conversation

@piyush-rj
Copy link
Copy Markdown
Contributor

@piyush-rj piyush-rj commented Dec 2, 2025

This PR fixes an issue where links added inside a note were not appearing in the preview shown under Company -> Notes. The link would only appear after opening the note, which led to inconsistent behavior.

Issue:
Blocknote represents text and links using different node types:

  1. { "type": "text", "text": "Welcome to this demo!" }
  2. {
    "type": "link",
    "content": { "type": "text", "text": "Example" },
    "href": "https://example.com"
    }

The existing preview function only handled plain text nodes and completely ignored link nodes.
As a result:

  • Links did not appear in the preview
  • Links appeared only inside the full note view

Steps to Reproduce:

  • Add a link inside a note
  • Go to Company / People and view the note preview -> the link is missing
  • Open the note -> the link appears correctly

How I fixed it:

  • A new recursive text extraction function (extractText) was added to correctly read.
  • Text nodes
  • Link nodes (including inner content and the href)
  • Nested child content
  • Link previews now appear in the following format:
    DisplayText (https://example.com)

Edit : closes #16043

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Dec 2, 2025

Greptile Overview

Greptile Summary

This PR successfully fixes the missing link preview issue by introducing a recursive extractText function that handles text nodes, link nodes, and nested content structures.

Key Changes:

  • Replaced simple content mapping with recursive text extraction
  • Link nodes now render as "DisplayText (https://example.com)" in previews
  • Handles nested content arrays recursively

Issues Found:

  • Uses any type in 4 locations, violating the codebase's strict TypeScript policy (no any allowed per typescript-guidelines.mdc)
  • Minor indentation inconsistency on line 10
  • No test cases added for the new link extraction functionality (existing tests only cover text and image nodes)

Confidence Score: 3/5

  • This PR is functional but has TypeScript violations that must be fixed before merging
  • The implementation correctly solves the link preview issue and the logic is sound. However, it violates the codebase's strict TypeScript guidelines by using any types in multiple places (lines 6, 15, 32), which is explicitly prohibited. The indentation inconsistency and missing test coverage for the new functionality are also concerns. These are fixable issues but should be addressed before merging.
  • packages/twenty-front/src/modules/activities/utils/getActivityPreview.ts requires TypeScript type fixes and test additions

Important Files Changed

File Analysis

Filename Score Overview
packages/twenty-front/src/modules/activities/utils/getActivityPreview.ts 3/5 added recursive text extraction for links; violates TypeScript strict mode with any types; missing test coverage for links

Sequence Diagram

sequenceDiagram
    participant NoteTile
    participant getActivityPreview
    participant extractText
    participant BlocknoteNode

    NoteTile->>getActivityPreview: activityBody (JSON string)
    getActivityPreview->>getActivityPreview: JSON.parse(activityBody)
    
    loop For each block in noteBody
        getActivityPreview->>extractText: node
        
        alt node.type === 'text'
            extractText-->>getActivityPreview: node.text
        else node.type === 'link'
            extractText->>extractText: recursively extract inner text
            extractText->>extractText: format as "innerText (href)"
            extractText-->>getActivityPreview: formatted link text
        else node has content array
            loop For each child in node.content
                extractText->>extractText: recursively extract child text
            end
            extractText-->>getActivityPreview: joined child text
        else
            extractText-->>getActivityPreview: empty string
        end
    end
    
    getActivityPreview->>getActivityPreview: filter empty strings
    getActivityPreview->>getActivityPreview: join with newlines
    getActivityPreview-->>NoteTile: preview text with links
Loading

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 2, 2025

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:33758

This environment will automatically shut down when the PR is closed or after 5 hours.

@etiennejouan etiennejouan self-assigned this Dec 3, 2025
Copy link
Copy Markdown
Contributor

@etiennejouan etiennejouan left a comment

Choose a reason for hiding this comment

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

Hi @piyush-rj, congrats for your first PR !! 👏
Good job, I took the liberty of updating the PR as it is small update.

Thank you for your contribution 🙏
Please, do not hesitate to tackle other issues.

@@ -1,16 +1,56 @@
// TODO: merge with getFirstNonEmptyLineOfRichText (and one duplicate I saw and also added a note on)
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.

Rem : Not sure we can remove this TODO

@@ -1,16 +1,56 @@
// TODO: merge with getFirstNonEmptyLineOfRichText (and one duplicate I saw and also added a note on)
// Basic Rich-Text Node Types
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.

nit : We avoid comment (in Twenty codebase). If you want to specify what is BaseNode, do not hesitate to be verbose :)

@@ -1,16 +1,56 @@
// TODO: merge with getFirstNonEmptyLineOfRichText (and one duplicate I saw and also added a note on)
// Basic Rich-Text Node Types
export interface BaseNode {
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.

nit : Do not export these type if they are not used elsewhere. And if in future, they are used in an other file, export them from their own file


switch (node.type) {
case 'text':
return (node as TextNode).text ?? '';
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.

nit : I prefer using type guard to avoid casting - not very useful here but good habit to take

.map(child => extractText(child))
.join('');
const href = linkNode.href ?? '';
return href ? `${innerText} (${href})` : innerText;
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.

I think we don't want to preview href as we don't see it in editor view

@charlesBochet charlesBochet merged commit 9c334b5 into twentyhq:main Dec 3, 2025
61 checks passed
@twenty-eng-sync
Copy link
Copy Markdown

Hey @charlesBochet! After you've done the QA of your Pull Request, you can mark it as done here. Thank you!

NotYen pushed a commit to NotYen/twenty-ym that referenced this pull request Dec 9, 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.

Links in note preview not visible

3 participants