Skip to content

Migrate autocomplete#8972

Draft
JYC333 wants to merge 51 commits intomainfrom
autocomplete
Draft

Migrate autocomplete#8972
JYC333 wants to merge 51 commits intomainfrom
autocomplete

Conversation

@JYC333
Copy link
Copy Markdown
Member

@JYC333 JYC333 commented Mar 9, 2026

This PR completes the migration from the legacy autocomplete.js integration to headless @algolia/autocomplete-core implementations across the client.

It replaces the old jQuery plugin usage in attribute and note autocomplete flows, updates React and non-React consumers to the new lifecycle, and preserves the existing product behavior around recent notes, command mode, keyboard shortcuts, IME handling, and custom selection events.

The change also introduces a shared headless autocomplete close registry, refreshes the CSS selectors for the new DOM structure, removes the obsolete autocomplete.js dependency and related jQuery polyfills, and cleans up leftover legacy selectors and dead styles.

Test coverage was expanded with unit tests for attribute enter-key handling, global autocomplete closing, and the React NoteAutocomplete wrapper. Validation completed with client type-check/build success plus targeted and full server E2E runs; the full Playwright suite still reports pre-existing flaky tests, but the autocomplete-specific updated spec passes.

All components listed below are tested manually to ensure they behave the same before and after migration.

  • Attribute Detail — verify attribute name autocomplete for both label and relation modes, including opening the panel, keyboard navigation, selecting an existing suggestion, and keeping the typed value when no suggestion is selected.
  • Attribute Detail — verify label value autocomplete, especially creating a brand-new label value that has never appeared in suggestions before and saving it with Ctrl+Enter / Cmd+Enter.
  • Attribute Detail — verify relation target note autocomplete, including selecting an existing target note, creating a new target note when allowed, and saving after selection.
  • Attribute Detail — verify outside click, tab switch, and dialog close behavior all close the autocomplete panel cleanly without leaving stale DOM behind.
  • Promoted Attributes — verify label value autocomplete still opens, filters, selects, and preserves manually typed values.
  • Promoted Attributes — verify relation target note selection through the React NoteAutocomplete wrapper.
  • Relation Map — verify relation name autocomplete still opens correctly, inserts the expected relation name, and does not regress keyboard behavior.
  • Jump to Note Dialog — verify recent notes are shown on open, standard note search still works, selecting a note still jumps correctly, and the last query is restored when the dialog reopens.
  • Jump to Note Dialog — verify command mode with > still lists commands, keyboard navigation works, and selecting a command triggers the expected action.
  • Jump to Note Dialog — verify Enter, Ctrl+Enter / Cmd+Enter, IME composition, and blur handling still match previous behavior.
  • Empty Note Page — verify recent notes are shown on mount, selecting a note opens it correctly, and the contained autocomplete panel has no border.
  • Add Link Dialog — verify recent notes on open, normal note search, keyboard selection, and link insertion after choosing a note.
  • Move To Dialog — verify note selection still updates the destination and the move action uses the chosen note.
  • Clone To Dialog — verify note selection still updates the destination and the clone action uses the chosen note.
  • Include Note Dialog — verify note selection still updates the include target and submission still works.
  • Note Type Chooser Dialog — verify note search and selection still set the target note type source correctly.
  • Bulk Action: Move Note — verify note autocomplete still resolves the destination note and submission applies the move.
  • Bulk Action: Add Relation — verify note autocomplete still resolves the target note and submission adds the relation.
  • Bulk Action: Update Relation Target — verify note autocomplete still resolves the replacement target note and submission updates the relation.
  • Collection Board — verify the board relation editor still searches and selects notes correctly.
  • Collection Table Columns — verify table column note selection still works through the React wrapper.
  • Render Widget — verify embedded note selection still updates the rendered target note correctly.
  • Search Definition Options — verify both note autocomplete fields still sync text, selected note id, and submission state correctly.
  • Global Headless Autocomplete Closing — verify opening or closing Bootstrap dialogs, changing tabs, and other global close triggers dismiss all open headless panels.
  • Cross-platform Input Behavior — verify IME composition, arrow navigation, Escape, plain Enter, and modifier-assisted Enter flows on the main autocomplete surfaces above.

close #5134

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request undertakes a significant refactoring effort to migrate the application's autocomplete functionality from an older jQuery-based library (autocomplete.js) to the more modern and flexible @algolia/autocomplete-js, specifically leveraging its headless core. This change aims to improve performance, maintainability, and user experience across various autocomplete instances, including attribute names, label values, and note search. The migration also addresses specific UI/UX issues and introduces new interaction patterns like Ctrl+Enter for confirmation.

Highlights

  • Migration Plan and Package: Added a migration plan and package for autocomplete.
  • New Autocomplete Registry: Introduced a new autocomplete registry.
  • Headless Autocomplete Implementation: Implemented headless autocomplete and migrated attribute detail functionality.
  • Dropdown Menu Positioning Fix: Fixed an issue where the dropdown menu did not follow the input when the attribute detail dialog height changed.
  • Relation Map Migration: Migrated relation map autocomplete.
  • Old Autocomplete Cleanup: Cleaned up the old autocomplete implementation.
  • Relation Definition Fix: Fixed an issue where relation definition was not included when creating a relation in the relation map.
  • Ctrl+Enter for Relation Creation: Implemented Ctrl+Enter to confirm relation creation in the relation map page.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .agents/migration_plan_autocomplete.md
    • Added a comprehensive migration plan document detailing the transition from autocomplete.js to @algolia/autocomplete-js, outlining architectural differences, key principles, functional areas, and a step-by-step migration process.
  • apps/client/package.json
    • Added @algolia/autocomplete-js as a new dependency.
  • apps/client/src/services/attribute_autocomplete.ts
    • Rewrote initAttributeNameAutocomplete to use @algolia/autocomplete-core for headless autocomplete, including custom DOM rendering and positioning logic for the dropdown panel.
    • Introduced instance tracking for managed autocomplete instances.
    • Updated initLabelValueAutocomplete to explicitly destroy and reinitialize the old autocomplete.js instance to prevent state retention issues.
  • apps/client/src/stylesheets/style.css
    • Added new CSS classes (.aa-core-panel, .aa-core-list, .aa-core-item, .aa-core-item--active) to style the custom-rendered dropdown panel for the headless autocomplete.
  • apps/client/src/widgets/attribute_widgets/attribute_detail.ts
    • Modified the call to attributeAutocompleteService.initAttributeNameAutocomplete to pass an onValueChange callback, allowing the attribute detail widget to react to autocomplete selections.
  • apps/client/src/widgets/dialogs/prompt.tsx
    • Changed the keyboard shortcut for the "OK" button in the prompt dialog from "Enter" to "ctrl+return".
    • Added a onKeyDown event handler to the input field to allow Ctrl+Enter (or Cmd+Enter on Mac) to submit the prompt dialog.
  • apps/server/src/services/attributes.ts
    • Enhanced the getAttributeNames function to also include attribute definitions (e.g., relation:* or label:*) when querying for relation or label attribute types, ensuring more comprehensive autocomplete suggestions.
Activity
  • Added a detailed migration plan and included the new autocomplete package.
  • Implemented a new registry for autocomplete instances.
  • Refactored to use headless autocomplete and migrated the attribute detail component.
  • Resolved an issue where the autocomplete dropdown did not correctly track the input field's position when the attribute detail dialog resized.
  • Migrated the autocomplete functionality within the relation map.
  • Removed the legacy autocomplete implementation.
  • Corrected a bug where relation definitions were omitted during relation creation in the relation map.
  • Introduced Ctrl+Enter as a confirmation shortcut for relation creation in the relation map.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request begins the migration from autocomplete.js to @algolia/autocomplete-js by refactoring the attribute name autocomplete to use a headless implementation with @algolia/autocomplete-core. The new implementation is well-structured, using requestAnimationFrame for positioning and a WeakMap for instance management. The PR also includes a backend fix to broaden attribute name suggestions and changes the submission shortcut in prompt dialogs to Ctrl+Enter.

My main feedback is regarding a memory and DOM leak in the new headless autocomplete implementation due to missing cleanup logic. Additionally, I've raised a concern about a hardcoded UX change in a generic prompt dialog, which could have unintended side effects in other parts of the application.

Note: Security Review did not run due to the size of the PR.

@TriliumNext TriliumNext deleted a comment from gemini-code-assist bot Mar 9, 2026
@JYC333
Copy link
Copy Markdown
Member Author

JYC333 commented Mar 9, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a great step forward in migrating from the legacy jQuery-based autocomplete.js to the modern @algolia/autocomplete-js. The migration plan is thorough, and the implementation correctly uses the headless @algolia/autocomplete-core to handle the application's need for multiple autocomplete instances. The shift from jQuery events to explicit callbacks is a significant improvement in code clarity and maintainability. My review includes a few suggestions to enhance maintainability and user experience by addressing code duplication, function naming, and a potentially sluggish timeout.

@JYC333
Copy link
Copy Markdown
Member Author

JYC333 commented Mar 9, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request migrates the autocomplete functionality from autocomplete.js to @algolia/autocomplete-js, modernizing the codebase and using @algolia/autocomplete-core for multiple instances. However, it introduces a critical Cross-Site Scripting (XSS) vulnerability. The new implementation uses innerHTML to render search suggestions with user-controlled data without proper sanitization, potentially allowing attackers to execute arbitrary scripts. Sanitize all HTML content intended for highlighting using a library like DOMPurify before rendering it via innerHTML to mitigate this risk. Additionally, consider the suggestion regarding code clarity and maintainability.

@JYC333
Copy link
Copy Markdown
Member Author

JYC333 commented Mar 10, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

这个 Pull Request 成功地将自动补全功能从旧的 autocomplete.js jQuery 插件迁移到了现代的 @algolia/autocomplete-js 库,特别是使用了其无头核心 @algolia/autocomplete-core 以实现更好的集成和控制。这些更改非常广泛,涉及属性自动补全、笔记搜索自动补全以及相关的 UI 组件和服务。新的实现结构良好,新的 autocomplete_core.ts 服务为无头设置提供了可复用的辅助函数。此次迁移还包括重构 jQuery 和 React 中的相关组件以适应新的 API,移除了旧的 polyfill,并更新了 E2E 测试使其更加健壮。总的来说,这是一次重要且执行良好的技术升级。我发现 PromptDialog 组件中有一个潜在的功能退化问题,需要处理一下。

@JYC333
Copy link
Copy Markdown
Member Author

JYC333 commented Mar 10, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully migrates the client's autocomplete functionality from the legacy autocomplete.js to the modern, headless @algolia/autocomplete-core. This is a substantial architectural improvement, introducing a well-structured service layer (autocomplete_core.ts) and updating numerous components and services to use the new implementation. The changes are accompanied by new unit tests, and existing e2e tests have been adapted. My review found one minor issue where the state was not fully cleared when the autocomplete panel closes with an empty input, which could be a slight regression from the previous behavior.

@JYC333 JYC333 marked this pull request as ready for review March 10, 2026 01:28
@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Mar 10, 2026
@JYC333
Copy link
Copy Markdown
Member Author

JYC333 commented Mar 10, 2026

@eliandoran This is quite a big migration, but all related behaviors are tested manually to ensure the migration doesn't break any existing functions. Please test a bit to see if I'm missing something. Would prefer an early merge to avoid repeatedly merging the main branch back. Thanks.

Copy link
Copy Markdown
Contributor

@eliandoran eliandoran left a comment

Choose a reason for hiding this comment

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

Manual testing seems to reveal some important issues:

  1. The hover style is completely missing.
  2. Typing too fast will slow down the application to a crawl. Reintroduce some kind of debouncing (there should already be a debouncing system but it seems that it's not being used).
  3. Double-check that the icon alignment and size is the same as previous.
  4. Sub-text (e.g. attributes) has a weird indentation.

Before implementing the fixes, it might be worth to look into:

  • From what I see, a lot of things had to be implemented from scratch such as rendering the actual elements. In this case, what's the role of the Autocomplete Core? Can't we get rid of this dependency as well and handle our own auto-completion system?

@eliandoran eliandoran marked this pull request as draft March 19, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-conflicts size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade autocomplete dependencies

3 participants